为什么“uniq --unique”不删除所有重复的行?

han*_*rik 3 uniq

跑步

printf "lol\nlol\nfoo\n\n\n\n\nbar\nlol\nlol\nfoo\nlol\nfoo" | uniq --unique
Run Code Online (Sandbox Code Playgroud)

印刷

foo
bar
foo
lol
foo
Run Code Online (Sandbox Code Playgroud)

为什么要foo打印三遍?不应该uniq --unique删除它们吗?

此外,值得注意的是,似乎删除了所有重复项lol。为什么删除了lol重复项,但没有删除foo重复项?

ter*_*don 11

uniqman uniq如果您希望它删除所有重复行,则需要对输入进行排序(from ):

描述

过滤来自 INPUT(或标准输入)的相邻匹配行,写入 OUTPUT(或标准输出)。

正如你在上面看到的,它只过滤相邻的匹配行。这就是lol删除 s 的原因。所以在传递给你之前对你的数据进行排序uniq

$ printf "lol\nlol\nfoo\n\n\n\n\nbar\nlol\nlol\nfoo\nlol\nfoo" | sort | uniq 

bar
foo
lol
Run Code Online (Sandbox Code Playgroud)

或者,使用 GNU sort,跳过uniq

$ printf "lol\nlol\nfoo\n\n\n\n\nbar\nlol\nlol\nfoo\nlol\nfoo" | sort --unique

bar
foo
lol
Run Code Online (Sandbox Code Playgroud)

最后,如果您想完全删除出现多次的行(而不是保留一个副本,默认行为),请使用uniq -u--unique在您的问题中使用:

$ printf "lol\nlol\nfoo\n\n\n\n\nbar\nlol\nlol\nfoo\nlol\nfoo" | sort | uniq -u
bar
Run Code Online (Sandbox Code Playgroud)

然而,在所有情况下,排序都是必要的。

  • @hanshenrik 不客气。是的,`awk` 工作正常_对于小数据集_。但是,由于它为每个非重复行保留一个数组条目,如果您在数组可能填满 RAM 的巨大数据集上尝试它,可能会导致问题。不过,对于常规大小的数据集来说绝对是好的。 (2认同)