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

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

跑步

printf "lol\nlol\nfoo\n\n\n\n\nbar\nlol\nlol\nfoo\nlol\nfoo" | uniq --unique

印刷

foo
bar
foo
lol
foo

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

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

答案1

uniqman uniq如果您希望删除输入,则需要对输入进行排序(来自)全部重复行:

描述

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

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

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

bar
foo
lol

或者,使用 GNU sort,跳过uniq

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

bar
foo
lol

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

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

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

答案2

您想问为什么foo仍在列表中吗?uniq只删除相邻的重复行,将相邻的重复行“挤压”成单行。使用-u(或--unique使用 GNU uniq),它还会删除具有相邻重复行的行。

在您的示例中,这三行中没有任何一行foo与任何其他行相邻foo。这就是它们被输出的原因。

被删除的行lol被删除是因为它们与另一行相邻,内容为lol。最后lol一行在这个意义上没有重复,因此被保留。

相关内容