$ cat data.txt
aaaaaa
aaaaaa
cccccc
aaaaaa
aaaaaa
bbbbbb
$ cat data.txt | uniq
aaaaaa
cccccc
aaaaaa
bbbbbb
$ cat data.txt | sort | uniq
aaaaaa
bbbbbb
cccccc
$
我需要的结果是显示原始文件中的所有行,删除所有重复项(不仅仅是连续的行),同时保持文件中语句的原始顺序。
在这个例子中,我实际寻找的结果是
aaaaaa
cccccc
bbbbbb
一般情况下我该如何执行这种通用uniq
操作?
答案1
perl -ne 'print unless $seen{$_}++' data.txt
或者,如果您必须有一个无用的使用cat
:
cat data.txt | perl -ne 'print unless $seen{$_}++'
以下是awk
针对缺少 Perl 的系统的翻译:
awk '!seen[$0]++' data.txt
cat data.txt | awk '!seen[$0]++'
答案2
约翰有一个工具叫做unique
:
usr@srv % cat data.txt | unique out
usr@srv % cat out
aaaaaa
cccccc
bbbbbb
要在单个命令行中不使用其他工具来实现相同的目标有点复杂:
usr@srv % cat data.txt | nl | sort -k 2 | uniq -f 1 | sort -n | sed 's/\s*[0-9]\+\s\+//'
aaaaaa
cccccc
bbbbbb
nl
在行前面打印行号,因此如果我们sort
/uniq
在行后面,我们可以恢复行的原始顺序。sed
之后只需删除行号;)
答案3
我更喜欢用这个:
cat -n data.txt | sort --key=2.1 -b -u | sort -n | cut -c8-
cat -n
添加行号,
sort --key=2.1 -b -u
对第二个字段(添加的行号之后)进行排序,忽略前导空格,保留唯一的行
sort -n
按严格的数字顺序排序
cut -c8-
保留从第 8 列到 EOL 的所有字符(即省略我们包含的行号)
答案4
使用乐(以前称为 Perl_6)
~$ raku -e '.put for lines.unique;' file
或者更多awk
-类似语法):
~$ raku -ne 'state %h; .put unless %h{$_}++ ;' file
输入示例:
aaaaaa
aaaaaa
cccccc
aaaaaa
aaaaaa
bbbbbb
示例输出:
aaaaaa
cccccc
bbbbbb