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


40
$ 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一般如何执行此广义操作?

Answers:


54
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]++'

3
一个稍短的awk脚本是{ if (!seen[$0]++) print }
camh 2011年

1
@fred,除非您的文件确实很大,否则任何一个版本的键入时间都比其运行时间更长。
cjm 2011年

8
awk的版本可以通过留出了进行更短ifprint:,括号,括号和awk '!seen[$0]++'
戈登戴维森

2
@Legate,它是一个数组的名称,我们在其中记录我们所看到的每一行。您可以将其更改'!LarryWall[$0]++'为所有awk关心的内容,但是“看到”可以帮助人们更好地理解该程序。
cjm 2012年

1
@Sadi,确实应该问这个问题,而不是评论。但是该文件中的某些行以空格结尾,而有些则没有。这些命令认为整行都很重要,包括末尾的空格。
cjm

13

john有一个名为的工具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只是随后删除行号;)


有什么通用的Linux命令组合可以做到相同吗?
Lazer

7
您在“无需排序数据”中错过了什么?
Totor 2013年

@Totor-参见menkus对类似评论的回复。@binfalse-您的第二个解决方案不起作用(也许它适用于这个简单的示例,但不适用于某些实际输入)。请修正该错误,例如,这应始终有效:nl -ba -nrz data.txt | sort -k2 -u | sort | cut -f2
don_crissti 2015年

6

我更喜欢使用这个:

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


5
>如何仅获得唯一结果而无需对数据进行排序?>无需排序数据
Jan Wikholm

7
“无需排序数据”仅出现在标题中。实际需要是:“显示原始文件中的所有行,以除去所有重复项(而不仅仅是连续的行),同时保持文件中语句的原始顺序。”
menkus 2013年

1
@menkus的关键是“同时保持文件中语句的原始顺序”。这个答案没有实现。
安德鲁·费里尔

2

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

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

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


这样可以处理大文件,例如500 GB吗?
男孩
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.