日历

2019年八月
« 5月    
 1234
567891011
12131415161718
19202122232425
262728293031  

最近评论

    AWK的使用

    awk的使用 第十四部分 awk的内部变量

        awk的内部变量的个数不多,在这里介绍的时候就不按照字母顺序排列了,而是按相关性分类说明。

        ARGC         
        ARGC表示命令行上除了选项-F,-v,-f等选项及其所对应的参数之外的所有参数的个数。如果将“awk程序”直接写在命令行上,那么ARGC是不会把“awk程序”计算在内的。

        ARGV         
        ARGV是一个数据,用来记录命令行上的参数的名称。 执行下列命令:
    [root@myfreelinux pub]# awk ‘BEGIN{printf(“ARGC=%d\n”,ARGC);for(a in ARGV)printf(“ARGV[%d]=%s\n”,a,ARGV[a]);}’ inte integer
    ARGC=3
    ARGV[0]=awk
    ARGV[1]=inte
    ARGV[2]=integer
        需要注意当ARGC = 3 时,命令列上只指定了2 个文件。
    awk的参数-F\t 表示以tab 为栏位分隔字符FS(field seporator);-v a=8 是用以初始化程序中的变量。

        FILENAME
        FILENAME用来表示目前正在处理的文件名。

        FS域分隔字符
        $0 表示目前awk所读入的数据行的内容,$1,$2…示所读入的数据行经过FS指定分割符分割后的第一域,第二域…的记过。
        说明:当awk读入一行数据行”A123  8:15″ 时,会先以$0 记录,即$0 = “A123  8:15″,如果程序中进一步使用了$1,$2…或 NF等内部变量时,awk才会自动分割 $0,以便取得各域的数据。 切割后各个域的数据会分別用$1,$2, $3…等存储。
        awk默认的(default)域分隔字符(FS)为空白字符(空格及tab)。以上例来说,如果没有改变FS的值,那么分割后:第一个域($1)=”A123″,第二个域($2)=”8:15″。也可以使用正则表达式来定义FS,比如FS=/[ \t:]+/,表示0或多个空格、tab、:分别或他们三个任意组合成的字符串作为分割符,awk每次需要分割数据行时,就会参考目前FS的值。 那么这定FS后,$0 = “A123  8:15″,将被分割为,第一个域($1) = “A123″,第二个域($2) = “8”,第三个域($3) = “15”。

         NR (number record)
       
    NR表示awk 开始执行该程序后所读取的数据行数。

       FNR (file number record)
       
    FNR 与NR功用类似;不同的是awk在处理多个数据文件的时候,每打开一个新的文件,FNR便从0重新累计,而NR是一直累加,看个列子更直观些,见下列:

    [root@myfreelinux pub]# cat inte
    123
    324
    [root@myfreelinux pub]# cat integer
    222 111
    333 111

    444 111
    [root@myfreelinux pub]# awk ‘BEGIN{print NR,FNR,$0}’ inte integer
    0 0
    [root@myfreelinux pub]# awk ‘{print NR,FNR,$0}’ inte integer
    1 1 123
    2 2 324
    3 1 222 111
    4 2 333 111
    5 3
    6 4 444 111

        NF (number field)
        NF表示当前行被域分隔符分割成的域的个数。awk 每读入一笔数据后,在程序中用NF记录该行数据包含的域的个数。在下一行数据被读入之前,NF不会改变。但如果使用$0来记录数据,例如:使用getline,此时NF将代表新的$0上数据的域的个数。

        OFS (output file separate)
       
    OFS输出分隔字符。默认是” “(一个空白)

        ORS (output Record separate)
        ORS输出数据分隔字符。默认值是”\n”(换行符)。

        OFMT(output format)
       
    OFMT数值数据的输出格式。默认值”%.6g”(若须要时最多印出6位小数)。

        当使用print指令一次打印出多项数据时,例如:print $1,$2,输出时,awk会自动在$1与$2之间补上一个域分隔符的值(OFS 之值);每次使用print输出后,awk会自动补上h行分隔符的值(ORS 之值)。使用print 输出数值数据时,awk将采用 OFMT 之值为输出格式。例如:
    [root@myfreelinux pub]# awk ‘BEGIN{print 2/3;OFS=”:”;OFMT=”%.2g”;print 2/3,1;}’
    0.666667
    0.67:1
        程序中通过改变OFS和OFMT的值,改变了指令print的输出格式。

        RS
        RS( Record Separator) :awk从文件上读取数据时,将根据RS的定义把数据切割成许多Records,awk一次只读入一个Record进行处理。RS 的默认值是换行符”\n”,所以一般awk一次仅读入一行数据。有时一个Record含括了几行数据(Multi-line Record),这情況下不能再以”\n” 来分隔相邻的Records,可改用空白行来分隔,即令RS = “”,表示以空白行来分隔相邻的Records。 

        RSTART
        RSTART与使用字串函数match( )有关的变量,是匹配的字符的开始的位置。
        RLENGTH
       
    RLENGTH与使用字串函数match( )有关的变量,RLENGTH是匹配的字符串的长度。当使用match() 函数后,awk会将match() 执行的结果以RSTART和RLENGTH记录。看下面的例子:
    [root@myfreelinux pub]# awk ‘BEGIN{match(“banana”,”an”);print RSTART,RLENGTH}’
    2 2
    [root@myfreelinux pub]# awk ‘BEGIN{match(“banana”,/(an)+/);print RSTART,RLENGTH}’
    2 4
    [root@myfreelinux pub]# awk ‘BEGIN{match(“banana”,/(na)+/);print RSTART,RLENGTH;}’
    3 4

        SUBSEP
       
    SUBSEP(Subscript Separator) 数组下标的分隔字符,默认值为”\034″实际上,awk中的数组只接受字串当它的下标,比如:  Arr[“John”]。但awk中仍然可使用数字当数组的下标,甚至可使用多维的数组(Multi-dimenisional Array),比 如:Arr[2,20]。事实上,awk在接受Arr[2,20]之前,就已先把其下标转换成字串”2\03420″,之后便以Arr[“2\03420”] 代替Arr[2,20]。可参考下例:
    [root@myfreelinux pub]# awk ‘BEGIN{arr[2,20]=13;print arr[2,20];print arr[“2\03420”];idx=2 SUBSEP 20;print arr[idx];}’
    13
    13
    13
     再看下面这个例子,统计每门课有几个学生选修,用课程名称作为数组的下标:
    [root@myfreelinux pub]# cat kecheng.dat
    zhangsan math english chinese
    lisi     computer chinese english
    wangwu dianzi chinese math
    zhaoliu huanjing english chinese
    [root@myfreelinux pub]# cat kecheng.awk
    #!/bin/awk -f
    {
    for(i=2;i<=NF;i++)
     array[$i]++;
    }
    END{
    for(one_array in array)
     print one_array,array[one_array];
    }
    [root@myfreelinux pub]# awk -f kecheng.awk kecheng.dat
    computer 1
    english 3
    dianzi 1
    chinese 4
    math 2
    huanjing 1

    评论已关闭。