文本处理三剑客之Gawk ✧

    AWK可以说是一种语言,他有着自己的语法,可以实现函数定义,变量赋值,条件选择(循环,判断,选择)…总之是值得深入研究一下的。

    AWK的起源:是个报告生成器,可以格式化文本输出内容,它的命名是由Aho,Weinberger,Kernighan三位作者首字母组合而成的,他有多个版本:New awk(nawk),GNU awk(gawk)。

blob.png

    gawk称为模式扫描和处理语言,它的基本用法如下:

        awk [options] 'program' var=value file…

        awk [options] -f programfile var=value file…

        awk [options] 'BEGIN{action;…}pattern{action;…}END{action;…}' file

    awk程序通常由:BEGIN语句块,能使用模式匹配的通用语句块,END语句块,共三部分

    program通常是存放在单引号中

    [options]:

        -F 指明输入使用道德字段分隔符

        -v var=value:自定义变量

    pattern和action:

        a.pattern部分决定动作语句何时触发及触发事件(BEGIN,END)

        b.action statements对数据进行处理,放在{}内指明(print,printf)


    分隔符,域和记录:

        1.awk执行时,由分隔符分割的字段(域)标记$1,$2…$n称为域标识,$0为所有域

          注意:和shell中变量$符含义不同                                        

        2.文件的每一行称为记录

        3.省略action,则默认执行print $0操作


    awk工作原理:

    STEP1:执行BEGIN{action;…}语句块中的语句

    STEP2:从文件或标准输入(stdin)读取一行,然后执行pattern{action;…}语句块,他逐行扫描文件,从第一行到最后一行重复这个过程,知道文件全部被读取完毕

    STEP3:当读至输入流末尾时,执行END{action;…}语句块

    BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化,打印输出表格的表头等语句通常卸载BEGIN语句块中

    END语句块在awk从输入流中读取玩完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,他也是可选语句块

  pattern语句块中的通用命令是最重要的部分,也是可选的,如果没有提供pattern语句块,则默认执行{print},即打印每一个读取到的行,awk读取的每一行都会执行该语句块。


    print格式:print item1,item2…

    要点:

    1)逗号分隔符

    2)输出的各item可以是字符串,也可以是数值,当前记录的字段,变量或者awk表达式

    3)省略item,相当于print $0

    blob.png


    awk变量:

    变量:内置和自定义变量

    FS:输入字段分隔符,默认为空白字符

    blob.png

    

    OFS:输出字段分隔符,默认为空白字符

    blob.png


    RS:输入记录分隔符,指定输入时的换行符,原换行符仍有效

        awk -v RS=' ' '{print }' /etc/passwd

    ORS:输出记录分隔符,输出时用指定符号代替换行符

        awk -v ORS=' ' '{print }' /etc/passwd

    NF:字段数量

        awk -F: '{print NF}' /etc/fstab 

  blob.png

        awk -F: '{print $(NF-1)}' /etc/fstab

    blob.png


    NR:显示行号

    行号是每读一行就显示该行号,而不是一次性显示共有多少行

    FNR:显示每个文件的行号,单独计数

    blob.png

    FILENAME:当前文件名

        awk '{print FILENAME}' /etc/fstab

    ARGC:命令行参数

        awk '{print ARGC}' /etc/fstab

        结果显示2,它有两个参数,第一个参数是awk自身,第二个参数为/etc/fstab

    ARGV:数组,保存的是命令行搜给定的各参数

        awk 'BEGIN{print ARGV[0]}' /etc/fstab –> awk

    blob.png


    AWK变量:

    自定义变量

    1)-v var=value

        变量名区分字符大小写

    2)在program中直接定义

        awk 'BEGIN{"name"="awk";print name}'

    blob.png


    printf命令

    格式化输出:printf "FORMAT",item1,item2,…

        1)必须指定FORMAT

        2)不会自动换行,需要显示给出换行控制符\n

        3)FORMAT中需要分别为后面每个item指定格式符

    格式符:与item一一对应

    blob.png

    修饰符:

        #[.#]:第一个数字控制显示的宽度,第二个数字表示小数点后的精度,%3.1f

        -:左对齐(默认右对齐)%-10s    

        +:显示数值的正负符号 %+d

    blob.png

   

    操作符:

    算数操作符:

        +,-,*,/,%,^

    字符串操作符:

        没有符号的操作符,字符串连接

    赋值操作符:

        =,+=,-=,*=,/=,%=,^=,++,–

    比较操作符:

        >,>=,<,<=,!=,==

    模式匹配符:

        ~:左边是否和右边匹配包含

        !~:是否不匹配

    blob.png    

    

    逻辑操作符:

    awk -F: '$3>=0&&$3<=1000{print $1}' /etc/passwd 显示所有系统用户的用户名

    awk -F: '$3==0||$3>1000{print $1}' /etc/passwd  显示root或者普通用户

    

    Pattern模式:

        根据pattern条件,过滤匹配的行,再做处理

        1)如果未指定:空模式,匹配每一行

        2)/regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来

            awk '/^root/{print }' /etc/passwd

        3) relation expression:关系表达式,结果有真有假,结果为真时才会被处理

            真:结果为非0值,非空字符串

            假:结果为空字符串

        blob.png

        blob.png

        seq 10 | awk 'i=!i'

        此执行结果为显示奇数行,seq 10 生成1~10的序列,i的初始值为0,!i则表示为非0,即为真,这样第一行就打印出来了,i=!i则i现在值为1,第一行结束,读第二行,!i,即非1,为假,所以这一行就不输出了,然后i被赋值为0,然后就这样继续循环下去,知道将序列中所有元素都读完,这样打印显示的就是奇数行


        4)line ranges:行范围

            startline,endline:/part1/,/part2/不支持直接给出数字格式

            awk -F: '/^root/,/^nobody/{print $1,$3}' /etc/passwd

            

        5) BEGIN/END模式

            BEGIN{}:仅在开始处理文本中的文本之前执行一次

            END{}: 仅在文本处理完成后执行一次

    blob.png


    AWK ACTION

    常用的action分类:

    1)Expression:算术,比较表达式等

    2)Control Statements:if,while等

    3)Compound Statements:组合语句

    4)Input Statements    

    5)Output Statements:print等


    控制语句之if-else

    语法:

       if(condition)statmement[else statement]

       if(condition1){statement1}else if{condition2}{statement2}else{statement3}

    使用场景:对awk取得的整行或某个字段做条件判断

    blob.png

    

    控制语句之while循环

    语法:while(condition)statement    

    条件‘真’,进入循环;条件‘假’,退出循环

    使用场景;

        对一行内的多个字段逐一类似处理时使用

        对数组中的各元素逐一处理时使用

    blob.png


    控制语句之do-while循环

    语法:do statement while(condition)

    意义:无论真假,先执行一次循环体

    

    控制语句之for循环

    语法:for(expr1,expr2,expr3…)statement

    for(variable assignment;condition;iteration process){for-body}

    特殊用法:能够遍历数组中的元素

        语法:for(var in array){for-body}

    blob.png

    参考性能方面的数据,可以知道awk的语句执行效率比其他几种循环遍历要高

    

    控制语句之switch

    语法:switch(expression){case value1 or /regexp/:statement;case value2 or /regexp2/:statement;…default:statement}

    

    break,continue,next

    break是退出循环体:break[n]

    continue是退出本次循环,开始新的一轮循环:continue[n]

    next提前结束对本行处理而直接进入下一行处理(awk自身循环)

    awk -F: '{if($3%2!=0)next;print $1,$3}' /etc/passwd

    blob.png


    awk数组    

    若要遍历数组中的每一个元素,要使用for循环

    for(var in arry){for-body}

        var会遍历数组array中的每一个索引

    

    awk函数

    数值处理:

        rand():返回0和1之间一个随机数

    awk 'BEGIN{srand();for(i=1;i<=10;i++)print int(rand()*100)}'

    blob.png

    

    字符串处理:

        length([s]):返回指定字符串的长度

        sub(s,r[,t]):对t字符串进行搜索s表示的模式匹配的内容,并将第一个匹配的内容替换为r

        gsub(s,r[,t]):对t字符串进行搜索s表示的模式匹配的内容,并将所有能匹配的内容替换为r

        split(s,array[,r]):以r分隔符切割s,并将切割后的结果保存在array所表示的数组中

    blob.png

    自定义函数:

    格式:

        function name(para1,para2…){

                    statements

                    return expression

        }


    awk中调用shell命令

    system命令:

        空格是awk中字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk的变量外其他一律用""引用起来

        awk 'BEGIN{system("hostname")}'

        awk 'BEGIN{a="awk";system("echo " a)}'


    将awk程序携程脚本,直接调用或执行

    blob.png    

    blob.png

    也可以向awk脚本传递参数

    格式:

        awk.awk var=value var2=value2 …inputfile

   blob.png 








        

原创文章,作者:Stupid_L,如若转载,请注明出处:http://www.178linux.com/48048