awk;


   文本处理三剑客;grep,sed,awk;

   grep系;grep,egrep,fgrep;基于pattern进行过滤文本;

   sed;流编辑器;行编辑器;模式空间,保持空间;

   awk;报告生成器,格式化文本输出工具;


 AWK;

   Alfred Aho;贝尔实验室;

   Peter 3 Weinberger,贝尔实验室;

   Brian Kernighan;贝尔实验室;K&R


 Centos RHEL系awk;GNU AWK,gawk

 Debian系awk;New awk;nawk


 GNU awk————gawk

    gawk - pattern scanning and processing language

    基本格式;

       awk [options] 'program' file...


       program;pattern(action statements;...)

         pattern;部分决定动作语句何时触发及通过什么事件来触发;

         BEGIN;END

       action statement对数据进行处理,通常放在一对()之中;

       print,printf


    分隔符;awk对数据进行处理时,会根据特定的标识对数据进行分段,这种特定标识就是分隔符,默认是空白字符


    字段;经过分隔符分割之后的每一个分段,都称为一个字段(field);默认awk会使用内置位置变量来存储各个字段的值,这些变量就是$1,$2,...$N;


    记录;有换行符分割的数据中的每一行;就是一个记录,在awk处理数据时;使用$0保存整行的内容


 awk工作原理;

   1.首先,执行BEGIN(action statements)语句块中的语句;

   2.其次,从支持中或者从标准输入读取一行,然后执行pattern(action statements)语句块;逐行重复处理该过程,直到数据全部被读取完毕;

   3.在其他语句执行完成后;在退出awk程序之前,执行END(action statements)语句块。


   注意;

     1).BEGIN语句块在awk开始处理数据之前就需要执行;此语句块是可选语句块

     2).END语句块在awk处理完所有数据之后,才会被执行;此语句块是可选语句块

     3).pattern语句块中的通用命令是最重要的部分,也是可选的;如果没有提供pattern语句块;则默认执行{ print }语句,显示数据的每一行;awk读取到的每一行都会被执行一次pattern语句块的内容;


  awk的基本用法;

    常用选项;

       -F;用来指明此次数据处理的字段分隔符,默认为空白字符

       -V;var=value;用于自定义变量和为自定义变量父域初始值


    常用的ACTION;

      1.print;标准格式显示;

        print iteml,item2,...


        print命令的要点;

          a.逗号分隔;

          b.输出的各item可以是字符串,也可以是数字;可以是当前记录中的字段;也可以是变量,也可以是awk的表达式;

          c.如果省略了item,就输出整行,相当于{print $0}


     示例;

       ~]# awk -F:'{print $1,$3,$7}' /etc/passwd

       ~]# echo -e "1 2 3\n4 5 6\n7 8 9" | awk '{print $2}'


      2.变量;

         内建变量

            FS;liput filed seperator,输入字段分隔符,默认是空白字符

               示例;

                 ~]# awk -v FS =';' '{print $1}' /erc/passwd


           OFS;outpit filed seperator,输出字段分隔符,默认空白字符

                示例;

                  ~]# awk -v FS=';' -v OFS=':' '{print $1,$3}' /etc/passwd


           RS;input record seperator,输入记录分隔符,默认换行符;

              示例;

                ~]# awk -v RS='/' '{print $0}' /etc/passwd


           注意;即使制定了新的输入记录分隔符,原换行符仍然有效;


           ORS;output record seperator,输出记录分隔符,默认换行符\n

            

           NF;number of field;字段数量

              示例;

                 ~]#  awk -v FS=':' '{print NF}' /etc/passwd

                 ~]#  awk -v FS=':' '{print $NF}' /etc/passwd

                 ~]#  awk -v FS=':' '{print $(NF-1)}' /etc/passwd


            NR;number of record,行数;鉴于awk遍历文件每行的特性;可以将该变量理解为行号;

                示例;

                  ~]# awk '{print FNR}' /etc/passwd /etc/fstab


           FILENAME;输出当前正在处理的文件的文件名;

              示例;

               ~]#  awk '{print FILENAME}' /etc/passwd

           ARGC;argement count,整个命令行中的参数的数量;包括命令行本身;

              示例;

              ~]#  awk '{print ARGC}' /etc/passwd /etc/fstab

           ARGV;数组,argument value,保存了命令行中各个参数的具体内容;

              示例;

              ~]#  awk '{print ARGV[1]}' /etc/passwd /etc/fstab


     自定义变量;

       1).定义方式;

          -v var=value

            注意;变量名区分字符大小写;


            示例;

            ~]#  awk -v varl='hello' -F: '{print varl ,$1' /etc/passwd




   3.printf命令;

       格式化输出命令;printf "FORMA" intem1,intem2,....

       

         要点;

           1).必须给出合适的FORMAT

           2).默认不自动换行,需要显示给出换行控制符(\n)

           3).FORMA中需要为后面的每一个item指定一个格式化符号;


           格式符;

              %c;显示字符的ASCII码

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

              %f;显示浮点数

              %e,%E;使用科学计数法显示数字

              %g,%G;使用科学计数法显示浮点数字

              %s;显示字符串

              %u;显示无符号输出

              %%;显示%自身


           修饰符;

             #[.#];第一个数字用来控制显示宽度,第二个数字表示小数点的精度;

                如:%3.1f   %5s

             -;表示采用左对齐机制;默认是右对齐;

             +;表示显示数字的正负符号;


           示例;

           ~]# awk -F: '{printf "%-20s: %-5s\n",$1,$3}' /etc/passwd


4.操作符:

算术操作符:

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

-x:将正数转换为负数;

+x:将字符串转换为数值;


字符串操作符:

没有符号的操作符,表示字符串连接之意;


赋值操作符:

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

++, --


比较操作符:

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


模式匹配操作符:

~:左侧的字符串是否能够被右侧的模式所匹配;

!~:左侧的字符串是否不能够被右侧的模式所匹配;


示例:

~]# awk -F: '$3==1000{print $0}' /etc/passwd

~]# awk -F: '$NF~/bash/{print $0}' /etc/passwd


逻辑操作符:

&&

||

!


示例:

~]# awk -F: '$3>=500&&$3<=1000{print}' /etc/passwd


条件表达式:

condition(selector)?if-true-expression:if-false-expression


示例:

~]# awk -F: '{$3>=1000?usertype="Common User":usertype="Super or System User";printf "%-20s: %-20s\n",usertype,$1}' /etc/passwd


5.PATTERN:

1) empty:空模式,处理文件中的每一行;

2) [!]/REGEXP/:仅处理[不]能被PATTERN匹配到的行;

示例:~]# awk '[!]/^r/{print}' /etc/passwd

3) 关系表达式:$3>=1000, $NF~/bash/

4) 行的范围:

关系表达式:($3>=500&&$3<=1000)

/regexp1/,/regexp2/:从被regexp1匹配的行开始到被regexp2匹配的行结束,有多少这一类匹配结果,就显示多少次;


示例:~]# awk '/^r/,/^a/{print}' /etc/passwd

5) BEGIN/END模式:

BEGIN{}:仅在开始处理文件中的第一行文本之前执行一次的语句块;

示例:

~]# awk -F: 'BEGIN{printf "%20s %5s\n","Username","UserID"}{printf "%20s %5s\n",$1,$3}' /etc/passwd

注意:在输出特定格式的表头时,常用此语句块;


END{}:仅在文本处理完成但命令尚未退出时执行一次的语句块;

示例:

~]# awk -F: 'BEGIN{printf "%20s %5s\n","Username","UserID"}{printf "%20s %5s\n",$1,$3}END{print "========================\n",NR " users"}' /etc/passwd


6.常用的ACTION:

1.表达式(Expression)

2.组合语句(Cpmpound Statement)

3.输入语句(Input Statement)

4.输出语句(Output Statement)

5.控制语句(Control Statement)


7.控制语句:

if (condition) statement [ else statement ]

while (condition) statement

do statement while (condition)

for (expr1; expr2; expr3) statement

for (var in array) statement

break

continue

delete array[index]

delete array

exit [ expression ]

{ statements }

switch (expression) {case value|regex : statement...[ default: statement ]}


1) if-else:

语法:if (condition) {statement} [ else {statement} ]

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


示例:

~]# awk -F: '{if($3>=1000) {print $1} else {print $1,$3}}' /etc/passwd


2) while循环:条件为真,进入循环;条件为假,退出循环;

语法:while (condition) statement

使用场景:对一行内的多个字段逐一做类似的处理时;对数组中的各个元素遍历及处理时;


示例:

~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {printf "%s: %d\n",$i,length($i);i++}}' /etc/grub2.cfg 


3) do...while循环:

语法:do statement while (condition)

意义:同while循环,但至少执行一次循环体中的语句;


4) for循环:

语法:for (expr1; expr2; expr3) statement

expr1:变量赋初值;

expr2:条件判断;

expr3:变量值的递增或递减调整;


示例:

~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {printf "%s: %d\n",$i,length($i)}}' /etc/grub2.cfg 

5) break 和 continue

break [n]

continue:跳过本次循环,直接进入下次循环;


6) next语句:

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

示例:

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


8.数组(Array)

关联数组:array[index_expression]

index_expression:

1) 可以使用任意的字符串,字符串必须使用双引号;

2) 如果某数组元素事先不存在,当引用该元素时,awk会自动创建此元素,并且为该元素赋"空字符串"作为其初始值;


注意:如果想要判断数组中某个元素是否存在,一般会使用"index in array"格式进行;


示例:

~]# awk 'BEGIN{name["leader"]="zhang";name["mem1"]="li";name["mem2"]="wang";print name["leader"]}'


查看已连接状态下,同一客户端的连接数量:

~]# ss -tn | awk '/^ESTAB\>/{print $NF}' | awk -F: '{state[$1]++}END{for(s in state){print state[s],s}}'


9.函数:

内建函数:

length():计算字符串长度

split(string,array[,fieldsep])


示例:

~]# awk '{split($0,user,":");print user[1]}' /etc/passwd