比较不同文件中的列并打印那些不匹配的列

时间:2017-02-10 17:46:43

标签: linux awk

我有两个文件,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

我在这里遇到的问题是找到那些匹配并打印它们的问题,而不是反之,那些不匹配的问题。

谢谢!

3 个答案:

答案 0 :(得分:3)

使用以下脚本:

awk '{k=$1 FS $2 FS $3 FS $4} NR==FNR{a[k]; next} !(k in a)' file1 file2

k是由1分隔的234FS列的连接值(请参阅{{ 3}}),稍后将用作搜索数组a中的键。在阅读NR==FNR时,truefile1。我在阅读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解决方案比这个更好,但是对于信息,这也可以使用uniqsortrev:< / p>

rev file1 file2 | sort -k3 | uniq -u -f2 | rev

rev正在从右向左恢复这两个文件。

sort -k3正在排序跳过第一列的第2列。

uniq -u -f2仅打印唯一的行(比较时首先跳过2)。

最后rev正在恢复线路。

此解决方案对两个文件的行进行排序。这可能是你想要的。