linux_awk的使用

awk的使用:
  awk : Aho,Kernighan,Weinberger
  new awk : nawk
  gawk,awk

  # awk [option] 'script' file...
  # awk [option] 'pattern {action}' file...


  awk的输出:
    一、print
         print item1,item2,...

       要点:
         1.各项目之间使用','隔开,输出时使用指定的分隔符分隔,默认的输入输出分隔符为空格
         2.输出的item可以为字符串或数值,当前记录的字段($1)、变量或awk的表达式;数值会转化为字符串之后再输出
       3.print命令后面的item可以省略,相当于{print $0};如果要输出空白,{print ""}

     例子:
        打印指定的字段
        [root@httpd tmp]# awk '{print $1}' test.txt
        this
        this
        [root@httpd tmp]# awk '{print $1,$2}' test.txt
        this is
        this is

        打印所有的字段
        [root@httpd tmp]# awk '{print $0}' test.txt
        this is like.
        this is love;

        在打印的字段中增加字符串,使用'#'作为输出分隔符
        [root@httpd tmp]# awk 'BEGIN{OFS="#"}{print $1,"hello",$2,$3}' test.txt
        this#hello#is#like.
        this#hello#is#love;

        对字符串进行处理
        [root@httpd tmp]# awk 'BEGIN{print "line one\nline two\nline three"}'
        line one
        line two
        line three

        指定输入分隔符和输出分隔符
        [root@httpd tmp]# head -1 /etc/passwd | awk -F: 'BEGIN{OFS=":"}{print }'
        root:x:0:0:root:/root:/bin/bash
        [root@httpd tmp]# head -1 /etc/passwd | awk 'BEGIN{FS=":";OFS="#"}{print $1,$3}'
        root#0
 
  二、awk的变量
       1.内置变量_记录变量:
         FS : 输入文本的分隔符,默认为空格
        OFS : 输出分隔符,默认空格
        RS : 输入文本的换行符: \n
        ORS : 输出换行符

       2.内置变量_数据变量:
         1.NR : awk命令所处理的记录数,总记录数
         2.FNR : 命令处理的当前文件的记录数,相对于当前处理的文件而言
         3.NF : 当前处理文本行的字段个数
         4.ARGV : 数组,保存命令行本身这个字符串;如awk '{print $0}' a.txt中,ARGV[0] 保存awk,ARGV[1]保存a.txt
         5.ARGC : awk命令的参数的个数
         6.FILENAME : awk命令处理的文件的名称
         7.ENVIRON : 当前shell环境变量及其值的关联数组

           [root@httpd tmp]# awk 'BEGIN{print ENVIRON["PATH"]}'
           /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
    
       3.用户自定义变量:
         允许用户自定义变量,命名变量规则只能使用字母,数字和下划线,但不能以数字开头

         [root@httpd tmp]# awk -v test="hellp awk" 'BEGIN {print test}'
         hellp awk
         [root@httpd tmp]# awk 'BEGIN{test="hello awk";print test}'
         hello awk
    

  三、printf
       printf命令的格式:
         printf format1format2...,item1,item2,...

       要点:
         1.其与print的最大区别是,必须制定format
         2.format用于指定后面每个item的输出格式
         3.printf语句不会自动打印换行符; \n

           format格式的指示符都以%开头,后面跟一个字符:
            %c : 显示字符的ASCII码
        %d,%i : 十进制整数
        %e,%E : 科学计数法显示数值
        %f : 显示浮点数
        %g,%G : 以科学计数法或浮点数的格式显示数值
        %s : 显示字符串
        %u : 无符号整数
        %% : %自身

              修饰符:用于对以上格式基础上的调整,修饰符位于'%'之后,格式字符之前
            N : 显示长度
            - : 左对齐;默认右对齐
            + : 显示数值符号
          
          awk '{printf "%-5s%-3s%-2s\n",$1,$2,$3}' test.txt


  四、输出重定向
      {print items > output_file}
      {print items >> output_file}


      特殊文件描述符:
         /dev/stdin : 标准输入
         /dev/stdout : 标准输出
         /dev/stderr : 错误输出
         /dev/fd/N : 某特定文件描述符,如/dev/stdin就相当于/dev/fd/0

       awk -F: '{printf "%-15s%-i\n",$1,$3 > "/dev/stdout"}' /etc/passwd

 
  五、awk的操作符:
       1.算术操作符:
         -x : 负值
         +x : 转换为数值
         x^y,x**y : x的y次方
         x*y : 乘法
         x/y : 除法
         x+y
         x-y
         x%y

       2.字符串操作符:
         只有一个,而且不需要显示写明,用于字符串的连接

       3.赋值操作符:
         =
         += : x += y --> x = x+y
         -= :
         *= :
          /= :
         %= :
         ^=,**= :


         ++ : x++  --> x=x+1
         -- :

       4.布尔值:
         awk中,任何非0值或非空字符串都为真,反之为假

       5.比较操作符:
         x为字符串,y为模式,用模式匹配字符串
         x < y
         x <= y
         x > y
         x >= y
         x == y
         x != y
         x ~ y : 如果x能被y匹配,返回true,否则返回false
         x !~ y

       6.表达式间的逻辑关系符:
         &&
         ||

       7.三目运算符:
         a>b?x:y  -->如果a>b为trun,返回x,否则返回y

       8.函数调用:
         function_name(paremeter1,parameter2,...)


  六、awk的模式:
       awk 'program' input_file1 input_file2 ...
         其中的program为:
         pattern {action}
         pattern {action}
         ...

       1、常见的模式类型:
         1.Regexp : 正则表达式,格式为 /Regexp/  
                    awk -F: '/^r/{print $1}' /etc/passwd
         2.express : 表达式,其值非0或非空字符时满足条件;如 $7 ~ "bash$"
                    awk -F: '$7~"bash$"{print $1,$7}' /etc/passwd
         3.range : 指定匹配的范围,格式 pat1,pat2
                    awk -F: '/^r/,/^m/{print $1,$7}' /etc/passwd
         4.BEGIN/END : 特殊模式,仅在awk命令执行前允许一次或结束前允许一次
                    awk -F: 'BEGIN{printf "%-20s%-50s\n","USERNAME","DEF_SHELL"}{printf "%-20s%-50s\n",$1,$7}END{print "End of report"}' /etc/passwd
         5.空模式,匹配输入的所有行
    
       
       2、常见的action:
         1、表达式
         2、控制语句
         3、符合语句
         4、输入
         5、输出

     if-else:
        语法: if(express){then-body} else {else-body}
          例子:
             awk -F: '{if ($1=="root") print $1,"Admin"; else print $1,"User"}' /etc/passwd
         awk -F: '{if ($1=="root") {print $1,"Admin"} else {print $1,"User"}}' /etc/passwd

         [root@httpd tmp]# awk -F: 'BEGIN {sum=0}{if ($3>500) sum++}END{print sum}' /etc/passwd
         1
         [root@httpd tmp]# awk -F: -v sum=0 '{if ($3>500) {sum++}}END{print sum}' /etc/passwd
         1


         while: 对行中的每一个字段进行循环
           语法: while (express){{while_body1};{while_body2}...}
            例子:
               awk -F: '{i=1;while (i<=NF) {if (length($i)>=4) {print $i};{i++}}}' /etc/passwd
         

        do-while:
           语法: do{while_body,...}while(express)
             例子:
                awk -F: '{i=1;do{if (length($i)>=4){print $i};i++}while(i<=NF)}' /etc/passwd

    
     for:
        语法:for (variable assignment;express;iteration process){body1,body2...}
          例子:
             awk -F: '{for(i=1;i<=NF;i++) {if (length($i)>=4){print $i}}}' /etc/passwd

 
 awk中使用数组:
       1.数组:
         array[index-express]
        index-express可以使用任意字符串;需要注意,如果某数组元素事先不存在,那么在引用其时,awk会自动创建此元素并初始化为空串;因此,要判断某数组中是否存在某元素,需要使用 index in  array 的方式
    
     要遍历数组中的每一个元素,需要使用下面的特殊结构:
     for (var in array){statement1,...}
        其中,var用于引用数组下标,而不是元素值

        例子:统计当前主机连接的各种状态的数量:
          netstat -tan | awk '/^tcp/{STATE[$NF]++}END{for(A in STATE){print A,STATE[A]}}'

posted @ 2016-01-07 15:06  Mr.hale  阅读(222)  评论(0编辑  收藏  举报