做系统运维时,经常需要对两个文件求并集、交集或差集,用临时表、脚本语言、Excel都可以处理,但不够方便,使用awk只需要简短一条语句就可以搞定,不过语法比较生涩难懂,下面讲一下这几条语句的执行过程。
两个数据文件如下:
a.txt
1111
2222
3333
4444
4444
b.txt
3333
4444
5555
6666
1、并集(去重)
awk '!A[$1]++' a.txt b.txt
执行结果:
1111
2222
3333
4444
5555
6666
执行过程说明:
1、awk处理第一行3333时,先读取A['3333']值为0 ,即awk '!0',条件为true,然后执行缺省的 {print} 打印3333,最后数组A['3333'] 自增值变为1。
2、awk处理第二行3333时, 读取A['3333']=1,即awk '!1',条件为false,不执行{print}
2、交集
awk 'NR==FNR{A[$0];next} ($0 in A)' a.txt b.txt
执行结果:
3333
4444
执行过程说明:
1、条件NR==FNR成立时,当前读入的是a.txt,执行{A[$0]; next},将a.txt文件每一行存入数组A,并使用$0做为下标引用,next类似于其它语言的continue。
2、条件NR==FNR不成立时,当前读入的是b.txt,($0 in A)语句判断b.txt的每行数据是否在A数组中,如果存在,则打印出该行数据。
3、差集(a -b)
awk 'NR==FNR{A[$0];next} !($0 in A)' b.txt a.txt
执行结果:
1111
2222
执行过程说明:
1、条件NR==FNR,当前读入的是b.txt,执行{A[$0];next}, 将b.txt文件存入数组A。
2、条件NR==FNR不成立时,当前读入的是a.txt,判断a.txt每行数据在A数组中如果不存在,则打印出该行数据