摘要
群里出现了一个文本文件对比的问题,我用awk写了,但是有些大神刁难我,让我说出命令的含义,就有了这篇文章,说实话我很喜欢做awk类的问题,但也很pa做awk类的问题,我awk普通的parint应该没什么问题,问题稍微复杂点,我估计就要卡壳半天了。。。。。甚至不知道咋办。。。。。。我自己有时候安慰自己不是我太笨是awk太高级。。。
[root@Legion100 ~]# cat 1.txt
2723216002
2723216005
2723216006
2723216007
2723216007
2723216002
[root@Legion100 ~]# cat 2.txt
2723216002
2723216008
2723216009
[root@Legion100 ~]#
[root@Legion100 ~]# awk 'NR==FNR{a[$0]}NR>FNR{if($0 in a){print$0}}' 1.txt 2.txt #简写(俗称装逼写法)
[root@Legion100 ~]# awk '{if (NR==FNR) {a[$0]}};{if (NR > FNR && $0 in a) {print $0}}' 1.txt 2.txt #完整写法
本人Linux初学者,要解释这awk只能用完整写法来说了,
[root@Legion100 ~]# awk '{print NR":"$0}' 1.txt 2.txt
1:2723216002
2:2723216005
3:2723216006
4:2723216007
5:2723216007
6:2723216002
7:2723216002
8:2723216008
9:2723216009
[root@Legion100 ~]# awk '{print FNR":"$0}' 1.txt 2.txt
1:2723216002
2:2723216005
3:2723216006
4:2723216007
5:2723216007
6:2723216002
1:2723216002
2:2723216008
3:2723216009
[root@Legion100 ~]#
[root@Legion100 ~]# awk '{if (NR==FNR) {a[$0]}};{if (NR > FNR && $0 in a) {print $0}}' 1.txt 2.txt
2723216002
[root@Legion100 ~]# awk '{if (NR==FNR) {a[$0]}};{if (NR > FNR && $0 in a) {print $0}}' 2.txt 1.txt
2723216002
2723216002
[root@Legion100 ~]# awk '{if (NR==FNR) {a[$0]}};{if (NR > FNR && $0 in a) {print FNR":"$0}}' 1.txt 2.txt
1:2723216002
[root@Legion100 ~]# awk '{if (NR==FNR) {a[$0]}};{if (NR > FNR && $0 in a) {print FNR":"$0}}' 2.txt 1.txt
1:2723216002
6:2723216002
[root@Legion100 ~]#
FNR:当前文件中的数据行行数
NR:以处理的输入数据行行数
FNR和NR的区别:FNR变量含有处理过的当前文件中的数据行总数,NR变量含有处理过的所有行总数,如上面的命令NR最大是9,FNR则是两个文件的行数。FNR的值在处理第二个文件的时候会被重置,而NR的值在处理第二个文件后继续计数的。所以说白了就是在处理一个文件的时候FNR值=NR值,处理多个文件的时候FNR的值在换文件的时候会被重置,NR的值是一直继续计数直到over。
{a[$0]}:这就是数组了,将处理行的行内容做数组a的索引值
$0 in a:这里的意思就是行内容是数组索引值(数组成员)
最后整个语句连起来的意思就是:我表达不出 自己脑补,要是你脑补也补不出,那就在浏览器上新开一个页面输入http://www.jd.com,点击搜索框,输入 sed与awk(第2版)然后购买此书,等书到了好好看看,多练习,自然就知道了
###找出两文件不同行
awk 'NR==FNR{a[$0]++;next} !a[$0]' filename1 filename2
awk 'FNR==NR {a[$0];next} !($0 in a)' filename1 filename2
awk 'NR==FNR{a[$0]++}NR>FNR && !a[$0]' filename1 filename2
awk 'NR==FNR{a[$0]}NR>FNR;{if(!($0 in a))print $0}' filename1 filename2
###找出两文件相同行
awk 'NR==FNR{a[$0]++;next} a[$0]' filename1 filename2
awk 'FNR==NR {a[$0];next} $0 in a' filename1 filename2
awk 'NR==FNR{a[$0]++}NR>FNR && a[$0]' filename1 filename2
awk 'NR==FNR{a[$0]}NR>FNR;{if($0 in a)print $0}' filename1 filename2