之前我问过一个问题:识别重复字段并使用 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
单独通过,请尝试:
- 首先,确保原始输入文件已排序,例如
sort unsorted_file > file
- 跑过您之前找到的 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
- 最后,用于
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
唯一发现的共同点file
file_3-6_dupes
- 因为我们想要相反的东西,所以我们只是
-3
抑制常见的东西,即重复的东西 - 需要注意的是,我们不需要额外的
-2
内容来抑制仅在文件 2 中的内容,在我们的例子中没有
因此,通过结合使用awk
、原始文件 和comm
,我们可以实现消除第 3-6 列重复行的目标。
尖端
- 如果原始版本
file
来自 Windows,非 Unix 行结尾可能会阻止comm
awk 生成的正常工作file_3-6_dupes
,因此如果您发现不起作用,可以继续运行,然后重试这些步骤,那么它应该可以dos2unix
工作file
comm