使用 awk 识别重复字段并删除它们

使用 awk 识别重复字段并删除它们

之前我问过一个问题:识别重复字段并使用 awk 打印它们

我有一个包含多列的文件,并且想要识别重复了特定列值(第 3-6 列)的行。

对此的答案是awk 'n=x[$3,$4,$5,$6]{print n"\n"$0;} {x[$3,$4,$5,$6]=$0;}' file

我现在遇到的问题是,我想从数据文件中删除使用上述代码标识的所有行,只留下从未重复的行。

我尝试使用!=代替,=但这给出了与 = 相同的结果或返回 0 行。我也尝试过: awk '!seen[$3, $4, $5, $6]++' file但这也保留了我想要删除的重复项的第一个实例。

答案1

尽管您正在寻找解决方案awk,但如果您的预期结果是消除重复项而不一定是awk单独通过,请尝试:

  1. 首先,确保原始输入文件已排序,例如sort unsorted_file > file
  2. 跑过您之前找到的 awk 命令用于识别第 3-6 列中的重复项,并将输出保存到文件中,例如file_3-6_dupes,在命令提示符下:
$ awk 'n=x[$3,$4,$5,$6]{print n"\n"$0;} {x[$3,$4,$5,$6]=$0;}' file > file_3-6_dupes
  1. 最后,用于comm消除重复项,将输出保存到文件中,例如file_3-6_uniques
$ comm -23 file file_3-6_dupes > file_3-6_uniques

这是如何运作的

  • 排序输入file是必要的,因为comm只有排序输入才能正常工作
  • awk命令不会改变它发现的重复项的出现顺序,它只是遵循它们在原始文件中的顺序,file所以实际上它只是file需要首先对原始文件进行排序
  • 默认情况下comm输出三列:仅在文件 1 中的行、仅在文件 2 中的行以及公共行
  • 文件1:file
  • 文件2:file_3-6_dupes
  • -number选项指定comm要抑制哪个输出列,
  • 所以-3意味着,抑制comm输出列3,这是常见的。
  • file_3-6_dupes其中仅包含重复项,派生自,因此这些重复项是和file唯一发现的共同点filefile_3-6_dupes
  • 因为我们想要相反的东西,所以我们只是-3抑制常见的东西,即重复的东西
  • 需要注意的是,我们不需要额外的-2内容来抑制仅在文件 2 中的内容,在我们的例子中没有

因此,通过结合使用awk、原始文件 和comm,我们可以实现消除第 3-6 列重复行的目标。

尖端

  • 如果原始版本file来自 Windows,非 Unix 行结尾可能会阻止commawk 生成的正常工作file_3-6_dupes,因此如果您发现不起作用,可以继续运行,然后重试这些步骤,那么它应该可以dos2unix工作filecomm

相关内容