it-swarm.cn

如何仅获得唯一结果而不必对数据进行排序?

$ 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操作?

43
Lazer
Perl -ne 'print unless $seen{$_}++' data.txt

或者,如果您必须使用 无用cat

cat data.txt | Perl -ne 'print unless $seen{$_}++'

对于缺少Perl的系统,这是awk的翻译:

awk '!seen[$0]++' data.txt
cat data.txt | awk '!seen[$0]++'
57
cjm

john 有一个名为unique的工具:

[email protected] % cat data.txt | unique out
[email protected] % cat out
aaaaaa
cccccc
bbbbbb

在单个命令行中不使用其他工具就可以实现相同的目标比较复杂:

[email protected] % 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之后会删除行号;)

13
binfalse

我更喜欢使用这个:

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(即,省略我们包含的行号)

6
menkus

Perl有一个可以使用的模块,其中包含一个名为uniq的函数。因此,如果您在Perl中将数据加载到数组中,则只需调用此函数即可使其唯一,但仍保持原始顺序。

use List::MoreUtils qw(uniq)    
@output = uniq(@output);

您可以在这里阅读有关此模块的更多信息: List :: MoreUtils

2
slm