0

我有多个 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或其他类型的递归工具可以用来实现我想要的结果?

4

2 回答 2

2

如果您不能在文件中复制 $2s,这样的东西(未经测试)将起作用:

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 第一次出现在每个文件中时增加 count[$2],例如

firstPass { if (!seen[FILENAME,$2]++) count[$2]++; next }
于 2015-02-20T14:07:01.733 回答
-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
于 2015-02-20T12:48:51.337 回答