十二、awk

       awk主要用于格式化报文、从文本文件中抽取数据包,下面着重讲述使用awk执行行操作及怎样从文本文件和字符串中抽取信息。

一、调用awk方式
    1、awk [-F field-separator] 'commands' input-file(s)
          awk中模式使用空格作为[-F 域分隔符]
    2、awk -F: 'commands' input-file
    3、将所有的awk命令插入一个单独文件,然后调用
   
    任何awk语句都由模式和动作组成
         模式可以是任何条件语句或复合语句或正则表达式。模式包括两个特殊字段BEGIN和END
         动作在{}中指定,如打印语句,if等控制语句


二、应用举例
      文件a.txt内容如下:
      no name sex tel
      1  a    m   110
      2  b    f   120
      3  c    m   114

   awk '{print $0}' a.txt | tee result.txt      ($0 ->表示所有域)
   结果:显示所有的内容
  
   awk '{print $1 "\t" $3}' a.txt | tee result.txt
   结果:显示第1、3列
  
   awk ' BEGIN {print "start\n---"} {print $1} END {print "---\nend"} ' a.txt | tee result.txt
   结果:
   start
   ---
   no
   1
   2
   3
   ---
   end

 

三、注意事项
    确保整个awk命令用单引号括起来。
    确保命令内所有引号成对出现。
    确保用花括号括起动作语句,用圆括号括起条件语句。
    可能忘记使用花括号,也许你认为没有必要,但awk不这样认为,将按之解释语法

 

四、awk与正则表达式和条件表达式的结合
    1、匹配
     awk '{if($4~/1/) print $0}' a.txt
     或  awk '$0' a.txt  ->
      1  a    m   110
      2  b    f   120
      3  c    m   114

      awk '$0 ~/4/' a.txt  ->
       3  c    m   114
    
     awk '{if($2~/[ab]/) print $0 }' a.txt ->
      1  a    m   110
      2  b    f   120

     不特殊声明,awk将打印整条记录,如awk '$2 ~ /b/' a.txt
     但 awk '{$2 ~ /b/}' a.txt 无结果输出,原因在于{}表示其中的是动作,此处并无任何动作,如print等

    2、精确匹配
    awk '$4=="110" {print $0}' a.txt  ->
    1  a    m   110
   
    awk '{if($2=="a" || $2=="b") print $0 }' a.txt   ->
      1  a    m   110
      2  b    f   120   
   
    awk '{if($1>2) print $0}' a.txt -》
      3  c    m   114
   
    awk '$0 ~ /(110|b)/' a.txt  ->  此处为关系匹配,匹配所有字段值为110或b,并打印所在行
      1  a    m   110
      2  b    f   120

    备注:
    1.用到的正则表达式字符为:\ ^ $ . [] | () * + ?         <备注:每个符号的代表的意思>
        +  使用+匹配一个或多个字符。
       ? 匹配模式出现频率。例如使用/XY?Z/匹配XYZ或YZ。
        ^  代表行首
    2.awk用到的条件表达式有< <= > >= == != ~ !~
    3.逻辑表达式
       && :语句两边必须同时匹配为真。
       || :语句两边同时或其中一边匹配为真。
       !  :非求逆

 

五:awk内置变量
      ARGC  命令行参数个数
      ARGV   命令行参数排列
      ENVIRON支持队列中系统环境变量的使用

      FILENAME awk正在浏览的文件名

      FNR  浏览文件的记录数
      FS     设置输入域分隔符,等价于命令行- F选项
      NF     浏览记录的域个数
      NR    已读的记录数
     OFS   输出域分隔符
     ORS  输出记录分隔符
     RS    控制记录分隔符
   
     举例:
    awk 'END {print NR}' a.txt  ->  4 
    awk '{print NF,NR,"\t",$0} END {print FILENAME}' a.txt b.txt  ->
     4 1  no name sex tel
     4 2  1  a    m   110
     4 3  2  b    f   120
     4 4  3  c    m   114
     4 5  no name sex tel
     4 6  10  a    m   110
     4 7  20  b    f   120
     4 8  30  c    m   114
     b.txt
    NF:
    a.最强大的一个功能就是将变量$PWD的返回值传入awk并显示其目录,这里需要指定域分隔符/   
        如:echo $PWD | awk -F/ '{print $NF}' -》返回当前所在的路径的目录名如 awk_file
    b.显示文件名
       如:echo "/opt/a/b/c" | awk -F/ '{print $NF}'   ->  c

 

六、awk操作符
    = += *= / = %= ^ = 赋值操作符
    ? 条件表达操作符
    || && ! 并、与、非
    ~!~ 匹配操作符,包括匹配和不匹配
    < <= == != >> 关系操作符
    + - * / % ^ 算术操作符
    + + -- 前缀和后缀
   
    1、设置输入域到域变量名
     awk '{a=$1;c=$4;if(c ~ /120/) print a " tel is " c }' a.txt  
     ->  2 tel is 120
     说明:这里将$1的值赋给变量a;$4的值赋给变量c
   
    2、域值的比较
     方式一:直接使用实际值进行比较
     awk '{if($1>2) print $0}' a.txt
     awk '{$1>2}' a.txt
      返回:
      no name sex tel
      3  c    m   114

    方式二:在BEGIN中使用变量
     awk 'BEGIN {a="2"} {if($1>a) print $0}' a.txt -》同上
   
    3、修改数值域取值<只是修改awk的副本,不会修改原文件>
     如: awk '{if($2=="a") $1=$1+1 ; print $0}' a.txt ->
              no name sex tel
             2  a    m   110     ->  此行的no已经+1
             2  b    f   120
             3  c    m   114

   
    4、修改文本域,也就是对其重新赋值
     如: awk '{if($2=="a") ($2="W") ; print $0}' a.txt    ->
             no name sex tel
            1 W m 110          -> 此行的name已被修改为W
            2  b    f   120
            3  c    m   114
  

七、内置的字符串函数
    gsub( r, s ) 在整个$0中用s替代r
    gsub( r, s , t ) 在整个t中用s替代r
    index( s , t ) 返回s中字符串t的第一位置
    length( s ) 返回s长度
    match( s , r ) 测试s是否包含匹配r的字符串
    split( s , a , fs ) 在fs上将s分成序列a
    sprint( f m t , e x p ) 返回经f m t格式化后的e x p
    sub( r, s ) 用$0中最左边最长的子串代替s
    substr( s , p ) 返回字符串s中从p开始的后缀部分
    substr( s , p , n ) 返回字符串s中从p开始长度为n的后缀部分
    gsub函数有点类似于s e d查找和替换。它允许替换一个字符串或字符为另一个字符串

    备注:gsub(r,s)和sub(r,s)的区别:
    gsub(r,s)对$0中所有的匹配项进行替换
    sub(r,s)只对第一次匹配到的项进行替换
        
 
    例:
    awk 'gsub(/1/,9) {print $0}' a.txt ->返回
    9  a    m   990
    2  b    f   920
    3  c    m   994


    awk 'gsub(/1/,9,$1) {print $0}' a.txt ->返回
     9 a m 110
   
    awk 'BEGIN {print index("abcce","c")}' ->返回
     3
    awk '$1=="1" {print length("abc"),"abc"}' a.txt ->返回
     3 abc

    awk 'BEGIN {print length("Hello World!")}' ->返回
     12

    #awk 'BEGIN {print match("abcd","a")}' ->匹配到,并显示位置
     1
    #awk 'BEGIN {print match("abcd","d")}'
     4
    #awk 'BEGIN {print match("abcd","f")}' ->未匹配到
     0
    #awk 'BEGIN {print match("abcd","h")}'
     0
    # awk 'BEGIN {print match("abcd",/c/)}'
     3
  
    # awk 'BEGIN {print split("a#b#c",arr,"#")}' ->返回数组下标3
     3 其中arr[1]="a" ; arr[2]="b" ; arr[3]="c"

    #awk 'sub(/1/,9) {print $0}' a.txt ->
     9  b    f   120

    #awk 'BEGIN {print substr("abcd",2,2)}' ->返回"abcd"中从第2个字符开始的前2个字符
     bc

    #awk 'BEGIN {print substr("abcd",3)}' ->省略掉第三个参数,将从指定位置的字符开始,返回之后所有的字符
     cd

 

八、从shell中想awk传入字符串
    echo "abcd" | awk 'gsub(/b/,"B")' -> aBcd
    echo "abcd" | awk '{print length($0)}' ->4

    STR="abc.txt"
    echo $STR | awk '{print substr($STR,1,5)}' ->abc.t

 

九、awk输出函数printf
    - 左对齐
    width域的步长,用0表示0步长
    .prec最大字符串长度,或小数点右边的位数

    %c ascii字符
    %d 整数
    %e 浮点数,科学记数法
    %f 浮点数,例如(123.44)
    %g awk决定使用哪种浮点数转换e或者f
    %o 八进制数
    %s 字符串
    %x 十六进制数

    echo "65" | awk '{printf "%c\n",$0}' ->A
    awk 'BEGIN {printf "%f\n",99}'  ->99.000000
    awk '{printf "%2s %2s\n",$1,$2}' a.txt ->
     no name
     1  a
     2  b
     3  c

 

十、awk数组
    awk 'BEGIN {print split("a#b#c",arr,"#")}'  -> 3


十一、实际中的应用例子
    1、查看该系统中的已注册的用户名
          awk -F: '{print $1}' /etc/passwd

   2、获取该目录下用户为root的文件,并记录到root_file.txt文件中
          ls -l | awk '{if($3=="root") print $9}'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值