例子转自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()函数第三个参数是子串长度,而不是子串结束位置的索引