2010-10-16 53 views
5

我有2个文件,第一个是包含以下内容:名字,这样的AWK/BASH:如何在一个文件中匹配另一个文件中的字段?

... 
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(或其他庆典命令)打印第一个文件中与第二个文件中的任何名称匹配的行(名称可以在第一个文件中重复)

Bonus?有没有简单的方法来删除第一个文件中的重复/重复行?

非常感谢,

托梅克

+0

如果有2条线相等,则留下一条。您是否定义了“删除”重复的行? – ghostdog74 2010-10-16 06:04:05

回答

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

您可以使用grep为:

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

grep-f选项来获得从文件搜索模式。

要从输出中删除精确复制行,你可以使用sort为:

grep -f file2 file1 | sort -u 
+0

我试图使用该命令,但得到了以下内容:“grep:Unmatched [或[^”,然后尝试使用-F强制执行,但没有输出?这个命令是否在一个搜索模式中使用全部file2来尝试匹配到file1? – Tomek 2010-10-16 05:48:42

+0

我指定了-F标志错误(我用-f替换了-f),所以最终的命令grep -f file2 -F file1起作用了。谢谢您的帮助。 – Tomek 2010-10-16 05:56:20

+0

为唯一,我正在寻找删除file1中只有名称重复的行(其他列有不同的数据) – Tomek 2010-10-16 06:00:34

1

扩大对codaddict的回答是:

grep -f file2 file1 | sort | uniq 

这将删除线是是完全一样的,但副作用(可能不需要)就是你的dat afile现在将被分类。 它还需要行确切相同,您的示例数据中不是这种情况。名称相同,但这些相同名称后的数据不同。 uniq可以选择一个字段或字符计数选项,但这不适用于您的数据,因为您的名称具有可变长度和可变数量的字段。如果你知道你的数据字段总是在一行的最后3个字段,那么你可以这样做:

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

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

+0

是的,这正是我的问题。名称可以是可变长度的,名称后面的数据是不同的。我只是希望得到约翰艾伦史密斯二世的第一次发生。我会用awk来研究一些关联数组。谢谢(你的)信息。 – Tomek 2010-10-16 06:12:29

相关问题