用awk数组处理的几个例子及学习心得

例子转自http://bbs.chinaunix.net/viewthread.php?tid=577044&extra=page%3D1%26filter%3Ddigest

 


 

1、用某一文件的一个域替换另一个文件中的的特定域? 
      http://bbs.chinaunix.net/forum/viewtopic.php?t=500015
      文件passwd: 
      s2002408030068:x:527:527::/home/dz02/s2002408030068:/bin/pw 
      s2002408032819:x:528:528::/home/dz02/s2002408032819:/bin/pw 
      s2002408032823:x:529:529::/home/dz02/s2002408032823:/bin/pw

      文件shadow: 
      s2002408030068:$1$d8NwFclG$v4ZTacfR2nsbC8BnVd3dn1:12676:0:99999:7::: 
      s2002408032819:$1$UAvNbHza$481Arvk1FmixCP6ZBDWHh0:12676:0:99999:7::: 
      s2002408032823:$1$U2eJ3oO1$bG.eKO8Zupe0TnyFhWX9Y.:12676:0:99999:7::: 

      用shadow文件中的密文部分替换passwd中的"x",生一个新passwd文件,如下所示
      s2002408030068:$1$d8NwFclG$v4ZTacfR2nsbC8BnVd3dn1:527:527::/home/dz02/s2002408030068:/bin/pw 
      s2002408032819:$1$UAvNbHza$481Arvk1FmixCP6ZBDWHh0:528:528::/home/dz02/s2002408032819:/bin/pw 
      s2002408032823:$1$U2eJ3oO1$bG.eKO8Zupe0TnyFhWX9Y.:529:529::/home/dz02/s2002408032823:/bin/pw 

 

      使用命令

            awk 'BEGIN {FS=OFS=":"} FNR=NR {a[$1]=$2} FNR<NR {$2=a[$1]; print}' shadow passwd > passwd_new

            mv passwd_new passwd

 

      解析:

            1)BEGIN中设定FS保证正确读取域,设定OFS保证使用print输出时格式正确

            2)FNR和NR:处理单个文件时,FNR和NR没有区别。但同时处理多个文件时,FNR对于每个文件都要重新计数,而NR把所有文件当作一个整体来计数,如file1和file2各有10行,则FNR范围是1,2,3,....,10,1,2,3,...,10,而NR是1,2,3,....,18,19,20。因此,可以说FNR和NR是在awk同时处理多文件时区别当前处理目标的重要标志。正因为此,本例中,awk命令后跟的文件名顺序不可颠倒,否则会产生错误的结果。

            3)本例中一个很巧妙的方法是使用了域$1作为数组的索引,这就将两个文件对应了起来

 

 


 

2、 
        cat file1: 
        0011AAA 200.00 20050321 
        0012BBB 300.00 20050621 
        0013DDD 400.00 20050622 
        0014FFF 500.00 20050401 

        cat file2: 
        I0011  11111 
        I0012  22222 
        I0014  55555 
        I0013  66666 

        规则:比较 file1的1-4字符 和 file2的2-5 字符,如果相同,将file2 的第二列 与 file1 合并 file3 

        0011AAA 200.00 20050321 11111 
        0012BBB 300.00 20050621 22222 
        0013DDD 400.00 20050622 66666 
        0014FFF 500.00 20050401 55555 

 

        使用命令:

                awk 'FNR==NR {a[substr($1, 2, 5)]=$2} FNR<NR&&a[substr($1, 1, 4)] {print $0,a[substr($1, 1, 4)]}' file2 file1 > file3

 

        解析:

                1)和例1一样,命令采用了两个文件相同的部分作为索引,这里引入了awk的取子串函数substr()

                2)因为awk默认分隔符为空格和制表符,所以此处不需要设置FS和OFS

                3)FNR<NR&&a[substr($1, 1, 4)]中,&&右侧判断数组元素值是否为0

 

 


 

3、如果文件a中包含文件b,则将文件b的记录打印出来
        http://bbs.chinaunix.net/forum/viewtopic.php?t=520411

        文件a: 
        10/05766798607,11/20050325191329,29/0.1,14/05766798607 
        10/05767158557,11/20050325191329,29/0.08,14/05767158557 

        文件b: 
        05766798607 
        05766798608 
        05766798609 
        通过文件a和文件b对比,导出这样的文件出来. 
        10/05766798607,11/20050325191329,29/0.1,14/05766798607

 

        使用命令:

                awk 'FNR==NR {array[$1]=$1} FNR<NR&&array[substr($0, 4, 11)] {print $0}' b a > c

 

        解析:

                1)本例中没有修改FS和OFS,即在文件a中将每一行看作一个域,然后取子串进行比较

                2)substr()函数第三个参数是子串长度,而不是子串结束位置的索引

 

 


 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值