日历

2019年十二月
« 11月    
 1
2345678
9101112131415
16171819202122
23242526272829
3031  

最近评论

    AWK的使用

    awk的使用 第十一部分 awk中常用的模式

       awk 通过判断模式(Pattern)的值来决定是否执行其后对应的动作(Actions)。首先来看一下awk中几个常见的模式,在前十部分中,有一些模式已经做了介绍,在这里再总结一下:           
      

      1、BEGIN是awk 的保留字,是一种特殊的模式。                
         BEGIN 成立(其值为true)的时机是:“awk 程序一开始执行,还没有读取任何数据之前”。 所以在BEGIN{ Actions} 语法中,Actions只在程序一开始执行时被执行一次。当awk 从数据文件读入数据行后,BEGIN 便不再成立,所以不论数据文件有多少数据行数据,Actions也不会被再次执行。一般情况下,把“与数据文件内容无关”和“只需执行ㄧ次”的部分放在以BEGIN 为模式的Actions中。
        比如:[root@myfreelinux pub]# cat BEGIN.awk
    #!/bin/awk -f
    BEGIN{
    FS=”[ \t:]+”; #设置awk分割字段的默认方式
    RS=””  #设置awk分割数据行的方式

    count=10; #设置count的初始值
    print “====This is title====” #打印标题行
    }
        有些awk程序不需要读入任何数据行,这情况可把整个程序写在以BEGIN 为模式的函数中,有时候也可以写在以END为模式的函数中,END后面介绍。
        例如:[root@myfreelinux pub]# awk ‘BEGIN{print “hello world!”}’会打印出“hello world!”,在awk语句后面则不需要有数据文件,这就是BEGIN模式的特点。

     2、END模式
        END是awk 的保留字,也是一个特殊的模式。END 成立(其值为true)的时机和BEGIN成立的时机正好相反,END成立的时机是:“awk 处理完所有数据, 即将离开程序时”,在平常读入数据行时,END模式不成立,所以END对应的Actions 并不被执行;只有当awk处理完所有数据后,END对应的Actions才会被执行。
        和BEGIN模式一样,不管数据文件有多少行数据,该Actions只被执行一次。

    3、关系表达式
        awk 中提供了很多关系运算符(Relation Operator)
        运算符   含意
        >             大于
        <             小于
        >=          大于或等于
        <=          小于或等于
        ==           等于
        !=             不等于
        ~               匹配 match
        !~              不匹配not match
        以上关系运算符除~(match)与!~(not match)外,和C 语言中的含意一样。 ~(match) 与!~(match) 在awk的含意简述如下: 如果A 为一字符串,B 为一正则表达式,那么A~B就是判断字符串A 中是否包含能匹配(match)B式样的子字符串;而A!~B是判断 字符串A 中是否没有包含能匹配(match)B式样的子字符串。
        例如:[root@myfreelinux pub]# awk ‘BEGIN{A=”abcdef”;B=”cd”;if(A~B){print A}}’,是判断A中是否有可以匹配B的子字符串,即“abcdef中是否包含有“cd”,如果有,则打印出A字符串。
        再比如$0 ~ /program[0-9]+\.c/,模式中被用来比对的字符串为$0 时,可只以正则表达式部分表示整个模式。所以这个表达式可以将模式部分$0 ~/program[0-9]+\.c/仅用/program[0- 9]+\.c/来表示,因为正则表达式中“.”有特殊含义,所以在这里使用\转义一下。

        4、正则表达式
        在awk中可以直接使用正则表达式当成模式;这是$0~ 正则表达式的简写。这种模式用来判断$0(数据行) 中是否含有匹配该正则表达式的子字符串;如果含有则成立(true)并执行其对应的Actions。
        例如:
    [root@myfreelinux pub]# echo “123”>inte
    [root@myfreelinux pub]# awk ‘{if(/^[0-9]+$/)print “this line is integer!”;}’ inte
    this line is integer!

    [root@myfreelinux pub]# awk ‘{if($0~/^[0-9]+$/)print “this line is integer!”;}’ inte  相同

        5、混合模式 
        以上介绍的4中模式计算后结果为一逻辑值(True or  False)。awk 各个逻辑值间可通过&&(and), ||(or),  !(not) 结合成一个新的逻辑值,所以可以将不同的逻辑值通过上述结合符号来结合成一个新的模式,这样可进行复杂的条件判断。
         例如: FNR >= 23 && FNR <= 28 { print ”     ” $0 }
        上式利用&& (and) 将两个模式求值的结果合并成一个逻辑值,该式将数据文件中第23行到28行向右移5格(先输出5个空白字符) 后输出。
        关于FNR在这里介绍一下,FNR同NR一样都是awk 的内建变量,awk有时候处理多个文件,NR会记录所有文件的行数,而FNR则每打开一个文件,FNR会重新计数打开文件的行数,举个例子看看:
    [root@myfreelinux pub]# cat inte
    123
    324
    [root@myfreelinux pub]# cat integer
    222
    333
    444
    [root@myfreelinux pub]# awk ‘{print NR,FNR}’ inte integer
    1 1
    2 2
    3 1
    4 2
    5 3
        上边结果中,左侧是NR输出地是行数,一直在增加,右侧是每个文件的行数,这就是NR和FNR的区别。
        6、模式1 , 模式2
        遇到这种模式,awk 会设立一个switch(或flag)。当awk读入的数据行使得模式1 成立时,awk 会打开(turn on)这switch。当awk读入的数据行使得模式2 成立时,awk 会关上(turn off)这个switch。该模式成立的条件是:当这个switch 被打开(turn on)时 (包括模式1, 或模式2 成立的情况)
        例如:FNR >= 23 && FNR <= 28 { print ”     ” $0 } 可改写为
                     FNR == 23 , FNR == 28 { print ”     ” $0 }
        说明:当FNR >= 23 时,awk 就turn on 这个switch;因为随着数据行的读入,awk不停的累加FNR。当 FNR = 28 时,模式2 (FNR == 28)  便成立,这时awk 会关上这个switch。 当switch 打开期间,awk 会执行  print ”     ” $0  ,关闭后,就不再打印了,也同样达到了相同的效果。

    评论已关闭。