使用shell比较多个文件的列

时间:2014-12-08 10:56:19

标签: sh

我必须根据第一列比较两个文件,如果它们匹配,则在同一行中打印file1和file2的第二列

档案1

  

1cu2 pf00959   
3nnr pf00440   
3nnr pf13972   
2v89 pf13341   
4aqb pf00431   
4aqb pf00431   
4aqb pf07645   
4aqb pf00084   
2liv pf13458   
2liv pf01094

文件2

  

1cu2 d.2.1.3   
2v89 g.50.1.2   
2v89 g.50.1.2   
2liv c.93.1.1   
2liv c.93.1.1   
1q2w b.47.1.4   
1q2w b.47.1.4   
1rr d.1.1.2   
1rr d.1.1.2   
1zxl c.2.1.2

输出

  

1cu2 pf00959 d.2.1.3   
2v89 pf13341 g.50.1.2   
2liv pf13458 c.93.1.1

1 个答案:

答案 0 :(得分:0)

假设您使用的不仅仅是Bourne(/bin/sh),您可以在一个班轮内执行此操作:

$ join <(sort -u file1) <(sort -u file2)
1cu2 pf00959 d.2.1.3
2liv pf01094 c.93.1.1
2liv pf13458 c.93.1.1
2v89 pf13341 g.50.1.2

如果您实际为/bin/sh编写shell脚本,则需要临时文件,例如

$ sort file1 > file1-sorted
$ sort file2 > file2-sorted
$ join file1-sorted file2-sorted

更新:您的示例输出每个键有一次命中,即使2liv在file1中有两个值。要完成此任务,您需要运行后处理器以记录重复项:

$ join <(sort -u file1) <(sort -u file2) |awk '!done[$1,$3] { print; done[$1,$3] = 1 }'
1cu2 pf00959 d.2.1.3
2liv pf01094 c.93.1.1
2v89 pf13341 g.50.1.2

这在awk中使用了一个简单的哈希。 sort -u项已经从file1(最终输出的第二列)中删除了重复项,因此我们只是在寻找第一个唯一的键配对与来自file2的值(第一个和第一个)第三栏)。如果我们找到一对新线,则会打印该线并保存该线对,以便在下次击中时不会打印。

请注意,这不是按照样本输出的方式排序的。这将是非常重要的(你需要第三份工作才能确定原始订单,然后将事情映射到它。)