使用Awk或类似文件从多个文件中删除重复项

时间:2015-02-20 12:33:25

标签: unix awk comm

我有多个不同长度的2列,制表符分隔文件,我想要消除所有文件中常见的重复值。

例如:

文件1:

9   1975
1518    a
5   a.m.
16  able
299 about
8   above
5   access

文件2:

6   a
6   abandoned
140 abby
37  able
388 about
17  above
6   accident

文件3:

5   10
8   99
23  1992
7   2002
29  237th
11  60s
8   77th
2175    a
5   a.m.
6   abandoned
32  able
370 about

文件4:

5   911
1699    a
19  able
311 about
21  above
6   abuse

所需的结果是从每个相应的文件中删除所有文件中常见的第2列中的项目。期望的结果如下:

文件1:

9   1975
5   a.m.
16  able
8   above
5   access

文件2:

6   abandoned
140 abby
37  able
17  above
6   accident

文件3:

5   10
8   99
23  1992
7   2002
29  237th
11  60s
8   77th
5   a.m.
6   abandoned
32  able

文件4:

5   911
19  able
21  above
6   abuse

查找重复值的某些标准方法不适用于此任务,因为我试图找到与多个文件重复的那些值。 因此,commsort/uniq之类的内容对此任务无效。 是否有某种类型的awk或其他类型的递归工具可以用来实现我想要的结果?

2 个答案:

答案 0 :(得分:2)

如果您在文件中无法复制$ 2,那么这样的(未经测试的)将起作用:

awk '
FNR==1 {
    if (seen[FILENAME]++) {
        firstPass = 0
        outfile = FILENAME "_new"
    }
    else {
        firstPass = 1
        numFiles++
        ARGV[ARGC++] = FILENAME
    }
}
firstPass { count[$2]++; next }
count[$2] != numFiles { print > outfile }
' file1 file2 file3 file4

如果你可以在一个文件中重复$ 2s,那么每次文件中第一次出现$ 2时,只会增加计数[$ 2],例如。

firstPass { if (!seen[FILENAME,$2]++) count[$2]++; next }

答案 1 :(得分:-1)

我还没有通过测试,但这应该可以解决问题。 这将创建扩展名为“.new”的文件。

awk '{a[$2]++;b[$2]=$0;c[$2]=FILENAME}
      END{
          for(i in a){if(a[i]==1)print b[i]>c[i]".new"}
      }' file1 file2 file3 file4