如何从文本文件中删除唯一字符串?

如何从文本文件中删除唯一字符串?

抱歉,我必须编辑我的示例,因为我没有正确表达我的查询。假设我有 .txt 文件:

Happy sad
Happy sad
Happy sad
Sad happy
Happy sad
Happy sad
Mad sad
Mad happy
Mad happy

我想删除任何唯一的字符串。留下文件:

Happy sad
Happy sad
Happy sad
Happy sad
Happy sad
Mad happy
Mad happy

我知道 sort 能够消除重复项 ( sort file.txt | uniq),那么我们是否可以使用命令在 bash 中执行相反的操作?或者我只需要找出一个 while 循环?顺便说一句uniq -D file.txt > output.txt,不起作用。

答案1

使用awk

$ awk 'seen[$0]++; seen[$0] == 2' file
Happy sad
Happy sad
Happy sad
Happy sad
Happy sad
Mad happy
Mad happy

这使用每行的文本作为关联数组的键seen。第一个seen[$0]++将导致打印之前已经见过的行,因为与该行关联的值在第二次及随后的时间看到该行时将不为零。seen[$0] == 2如果这是第二次看到该行,则会再次打印该行(否则,您将错过每个重复行的一次出现)。

这与 awk '!seen[$0]++'有时用于消除重复而不排序(参见例如awk '!a[$0]++' 是如何工作的?)。


仅获取重复行的一份副本:

awk 'seen[$0]++ == 1' file

或者,

sort file | uniq -d

答案2

如果重复项可能不连续并且您需要保留输入中的顺序,则可以使用awk两遍来完成此操作,一次用于计算出现次数,另一次用于打印在中出现多次的行第一遍:

awk 'second_pass {if (c[$0] > 1) print; next}
     {c[$0]++}' file.txt second_pass=1 file.txt

答案3

man uniq

-D 打印所有重复行

您可以像这样实现您的目标:

uniq -D file.txt

答案4

这可能是仅限 Linux 的解决方案,因为它使用uniq's-u选项。如果您正在运行其他版本,您可以通过使用uniq -cthen 过滤等来解决这个问题。^ *1

sort < in | uniq --unique | grep --invert-match --line-regexp --fixed-strings --file - in

前2阶段将推出

Mad sad
Sad happy

下一阶段将删除与这些行完全匹配的行。为了清晰起见,我选择了较长的选项;我自己很少使用它们简短的形式是sort < in | uniq -u | grep -v -x -F -f - in

相关内容