AWK / BASH:如何匹配一个文件中的字段与另一个文件中的字段?

时间:2010-10-16 05:31:45

标签: bash shell file awk

我有2个文件,第一个包含以下内容:

...
John Allen Smith II 16 555-555-5555 10/24/2010
John Allen Smith II 3 555-555-5555 10/24/2010
John Allen Smith II 17 555-555-5555 10/24/2010
John Doe 16 555-555-5555 10/24/2010
Jane Smith 16 555-555-5555 9/16/2010
Jane Smith 00 555-555-5555 10/24/2010
...

,第二个文件是名称列表,所以......

...
John Allen Smith II
John Doe
Jane Smith
...

是否可以使用awk(或其他bash命令)打印第一个文件中与第二个文件中的任何名称匹配的行(名称可以在第一个文件中重复)

红利?有没有一种简单的方法可以删除第一个文件中的重复/重复行?

非常感谢,

托梅克

3 个答案:

答案 0 :(得分:3)

AWK

#! /bin/bash
awk 'FNR==NR{!a[$0]++;next }{ b[$0]++ }
END{
  for(i in a){
    for(k in b){
      if (a[i]==1 && i ~ k ) { print i }
    }
  }
}' file1 file2

答案 1 :(得分:1)

您可以将grep用作:

grep -f file2 file1   # file2 is the file with the names.

-f的{​​{1}}选项从文件中获取要搜索的模式。

要从输出中删除完全重复的行,您可以将grep用作:

sort

答案 2 :(得分:1)

扩大了对于codaddict的回答:

grep -f file2 file1 | sort | uniq

这将删除完全相同的行,但副作用(可能不需要)是您的数据文件现在将被排序。 它还要求线条完全相同,这与示例数据中的情况不同。名称相同,但这些名称后的数据不同。 uniq可以使用字段或字符计数选项,但这不适用于您的数据,因为您的名称具有可变长度和可变数量的字段。如果您知道您的数据字段始终是一行中的最后3个字段,那么您可以这样做:

grep -f file2 file1 | sort | rev | uniq -f 3 | rev

你的输出只是每个名字中的一个,但是哪一个?按字典顺序排列的最低值,因为它已排序(sort需要uniq才能正常工作)。如果你不想先对它进行排序,或者需要注意哪些行被删除,那么awk或perl或者ruby或python解决方案可能最好使用关联数组。