繁体   English   中英

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

[英]compare columns from different files and print those that DO NOT match

我有两个文件,file1和file2。 我想比较file1的几列-$ 1,$ 2,$ 3和$ 4与file2的几列$ 1,$ 2,$ 3和$ 4,并打印出与file1中的任何行都不匹配的file2行。

例如

文件1

aaa bbb ccc 1 2 3
aaa ccc eee 4 5 6
fff sss sss 7 8 9

文件2

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

我想作为输出:

mmm nnn ooo 1 d e
ppp qqq rrr 4 e a
sss ttt uuu 7 m n

我在这里看到了一些问题,这些问题是寻找匹配的问题并打印出来的,反之则不匹配的问题。

谢谢!

使用以下脚本:

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

k是各列的连接的值1234 ,由分隔FS (见注释 ),以及将被用作在搜索阵列的关键a后面。 读取file1 NR==FNRtrue 我在读取file1同时创建了ak索引的数组。

对于其余的输入行,我用!(k in a)检查索引是否在a中不存在。 如果计算结果为true awk将打印该行。

如果文件已排序并且知道使用的字符集,则这是另一种方法。

$ 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

毫无疑问,@ hek2mgl的awk解决方案比此解决方案要好,但是对于信息来说,也可以使用uniqsortrev

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

rev正在将两个文件从右还原到左。

sort -k3正在跳过第一列的第二行。

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

最后, rev恢复到原来的水平。

此解决方案对两个文件的行进行排序。 这可能是希望的,也可能不是。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM