之前给大家讲述了文本处理三剑客前两种,grepsed。但是这周学习了第三种awk,感觉awk比前两个功能还要强大,相比sed也是以行进行处理,但是awk能以每一行的间隔符进行处理,用起来会更加方便。因此决定这周给大家详细介绍介绍awk

awk的基本用法:awk [options] pattern{action statements;..} filename

一、options

    -F 指定间隔符

    -v 指定变量

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

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

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

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

    变量:NF:字段数量

          NR:行号

          FNR:各文件分别计数,行号

          FILENAME:当前文件名

          ARGC:命令行参数的个数

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

    还能自己定义变量:-v var=“定义变量”,在后面引用时候不用加$

    -f:调用文件内容

    wKioL1nGFJPj1C5rAAAo9hmt3VM937.png

二、pattern

    BEGIN{头部信息}{print}    自己定义头部信息BEGIN可以后面不用带文件   

    END{}  awk从输入中读取完所有的行之后即被执行

    wKioL1nGFMiAY980AAAWjImMves435.jpg

    //  还可以用正则匹配行

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

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

        (3) relational expression: 关系表达式,结果为“真”才会被处理

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

            假:结果为空字符串或0

        (4) line ranges:行范围 startline,endline/pat1/,/pat2/ 不支持直接给出数字格式

    例子:打印/etc/passwd/奇数行和偶数行

    打印奇数行:

    wKiom1nGFXTSX3jxAAB4LBAtoyg416.jpg

    打印偶数行:

    wKiom1nGFZSDUy6sAABvNf3Xs8w060.jpg

三、print

    printf FORMAT, item1, item2, ...

    特点:(1) 必须指定FORMAT

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

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

    格式符:%c: 显示字符的ASCII

 %d, %i: 显示十进制整数

 %e, %E:显示科学计数法数值

 %f:显示为浮点数

 %g, %G:以科学计数法或浮点形式显示数值

 %s:显示字符串

 %u:无符号整数

 %%: 显示%自身

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

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

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

    例如:取出/etc/passwd的第一列和第三列,第一列左对齐,第三列取3个小数点

    wKioL1nGFcGhy_FvAAAxXLZluys625.jpg   

    printf 里面有几个%号,就对应后面有几个变量,切数据是一一对应的

四、操作符

    算术操作符:

x+y, x-y, x*y, x/y, x^y, x%y

-x: 转换为负数

+x: 转换为数值

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

    赋值操作符:

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

    比较操作符: = =, !=, >, >=, <, <=

    模式匹配符:

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

!~:是否不匹配

    例如:检测磁盘使用率是否超过百分之十

    wKiom1nGFmTzs9SEAAAUsukJQsM830.jpg

    逻辑操作符:&& ||

      &&awk中表示切的意思,不是bash的短路与

      ||awk中表示或的意思,不是bash的短路非

    例子:取/etc/passwd里卖的49

    wKiom1nGFrXxnYBoAABOSOscugU453.jpg

    条件表达式(三目表达式):

selector?if-true-expression:if-false-expression

如果selector为真就执行?后面的,如果为假就执行:后面的

五、 action

    (1if的用法:if(判断语句){命令}[else 命令]

        如果只是一条命令,就不需要加{}

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

    例如:统计日志里面访问IP地址最多的直接禁用。但是bash里面的命令不能直接在awk里面用,如果想用需要加入system("hostname")

    wKioL1nGFr3wim6ZAAAZnXYATlc329.jpg

2while的用法:while(判断语句){循环体}

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

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

    例子:显示/etc/passwd下的以:为间隔符,每个字段的字节数

    wKiom1nGFyWyiqPgAAAYauiVCis886.jpg

3do-while的用法:do{循环体}while(判断语句)

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

    例子:计算前100的和

    wKioL1nGFw7yD5sZAAASdeRx_ZU821.jpg

4for的用法:for(expr1;expr2;expr3){命令}

        特殊的用法:for(var in array) {for-body}

    例子:算出/etc/grub2.cfg中带linux16的行每个字符串多少个

    wKiom1nGF2eCKHgkAAA2Mnfiri8863.jpg

5breakcontinue的用法

    例子:奇数和

    wKioL1nGF0jy5kvkAAAS14D-gCw361.jpg    

    例子:从1加到100,如果等于66就退出循环

    wKioL1nGF2rQevqlAAAXcyPYsSM388.jpg

6next的用法

    提前结束对本行处理而直接进入下一行处理

六、awk数组(默认用的是关联数组)

    (1)可使用任意字符串;字符串要使用双引号括起来

    (2)如果某书元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”

    若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历

    for遍历数组 for(i in title){print i title[i]}

    wKiom1nGF93xgtDhAAAj5vCeueo208.jpg

七、awk函数

    1rand生成随机数

       int 对数字取整

    例如:取出1-50随机数

        bash中:echo $[RANDOM%50+1]

    wKiom1nGGA-AN-3MAAAmP5hyDO0336.jpg

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

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

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

    例如:

    wKioL1nGGAKx-XnAAAAqDEZaEfY531.jpg

    5split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二个索引值为2.....

    例子:统计IP地址重复的次数

    wKioL1nGGCzSCDkrAAAZYaatf84216.jpg

    6、可以自己定义函

    格式:function name(虚拟参数1,虚拟参数2...){

                        命令行

                        return expression(返回一个具体的值)

          }

看完以上awk的用法是不是感觉跟bash用法大同小异,所以在文本处理三剑客中感觉awk用处相对于前两个用法更广。