我有两个文件,file1和file2。我想比较几个列 - $ 1,$ 2,$ 3和$ 4的file1,其中列为$ 1,$ 2,$ 3和$ 4的file2,并打印那些与file1中的任何行都不匹配的file2行。
E.g。
文件1
<div id="main-menu">
<div class="container">
<div class="row">
<div class="col-md-9"><module type="menu" /></div>
<div class="col-md-3" id="header-search"><div id="hamburger"></div><module type="search" template="autocomplete" /></div>
</div>
</div>
</div>
file2的
aaa bbb ccc 1 2 3
aaa ccc eee 4 5 6
fff sss sss 7 8 9
我想要输出:
aaa bbb ccc 1 f a
mmm nnn ooo 1 d e
aaa ccc eee 4 a b
ppp qqq rrr 4 e a
sss ttt uuu 7 m n
fff sss sss 7 5 6
我在这里遇到的问题是找到那些匹配并打印它们的问题,而不是反之,那些不匹配的问题。
谢谢!
答案 0 :(得分:3)
使用以下脚本:
awk '{k=$1 FS $2 FS $3 FS $4} NR==FNR{a[k]; next} !(k in a)' file1 file2
k
是由1
分隔的2
,3
,4
和FS
列的连接值(请参阅{{ 3}}),稍后将用作搜索数组a
中的键。在阅读NR==FNR
时,true
为file1
。我在阅读a
时正在创建由k
编制索引的数组file1
。
对于剩余的输入行,如果!(k in a)
中的索引不存在,我会使用a
进行检查。如果评估结果为true
awk
,则会打印该行。
答案 1 :(得分:3)
这是另一种方法,如果文件已经排序,你知道使用过的字符集。
$ function f(){ sed 's/ /~/g;s/~/ /4g' $1; }; join -v2 <(f file1) <(f file2) |
sed 's/~/ /g'
mmm nnn ooo 1 d e
aaa ccc eee 4 a b
ppp qqq rrr 4 e a
sss ttt uuu 7 m n
fff sss sss 7 5 6
通过连接前四个字段(使用~
字符创建一个键字段,但可以使用任何未使用的字符),使用join
从file2中查找不匹配的条目并对合成键字段进行分区背部。
但是,最好的方法是使用awk
解决方案进行轻微修复
$ awk 'NR==FNR{a[$1,$2,$3,$4]; next} !(($1,$2,$3,$4) in a)' file1 file2
答案 2 :(得分:1)
毫无疑问,来自@ hek2mgl的awk
解决方案比这个更好,但是对于信息,这也可以使用uniq
,sort
和rev
:< / p>
rev file1 file2 | sort -k3 | uniq -u -f2 | rev
rev
正在从右向左恢复这两个文件。
sort -k3
正在排序跳过第一列的第2列。
uniq -u -f2
仅打印唯一的行(比较时首先跳过2)。
最后rev
正在恢复线路。
此解决方案对两个文件的行进行排序。这可能是你想要的。