尽管多次出现,但只会打印一次值的命令


8

我有一个很大的txt文件,其中的值重复了很多次。我是否可以使用某些命令来遍历文件,如果一次出现一个值,请不要重复此命令?

SO4
HOH
CL
BME
HOH
SO4
HOH
CL
BME
HOH
SO4
HOH
SO4
HOH
CL
BME
HOH
SO4
HOH
CL
BME
HOH
CL

所以它应该看起来像这样:

S04   
HOH  
CL   
BME 

问题是我有很多不同的值,所以不能像这里一样手动进行。

Answers:


11

您可以将命令sort与选项一起使用--unique

sort -u input-file

如果要将结果写到FILE而不是标准输出,请使用以下选项--output=FILE

sort -u input-file -o output-file

该命令uniq也可以应用。在这种情况下,必须使用相同的行,因此必须对输入进行初步排序-感谢@RonJohn提供注释:

sort input-file | uniq > output-file

我喜欢sort类似情况下的命令,因为它很简单,但是如果使用大型数组awk,John1024的答案可能会更有效。下面是上述方法之间的时间比较,这些方法应用于具有近500万行的文件(基于上述示例):

$ cat input-file | wc -l
20000000

$ TIMEFORMAT=%R
$ time sort -u input-file | wc -l
64
7.495

$ time sort input-file | uniq | wc -l
64
7.703

$ time awk '!a[$0]++' input-file | wc -l      # from John1024's answer
64
1.271

$ time datamash rmdup 1 < input-file | wc -l  # from αғsнιη's answer
64
0.770

其他显著差异在于提及@Ruslan

sort -u仅在输入结束后才打印结果,而此awk命令将即时打印每个新的结果行(这对于管道输入比文件更重要)。

这是一个例子:

在此处输入图片说明

在上面的示例中,循环(如下所示)生成了字母AD的500个随机组合,每个组合的长度为三个字符。这些组合通过管道传递给awksort

for i in {1..500}; do cat /dev/urandom | tr -dc A-D | head -c 3; echo; done

1
这是非常简单的命令!非常感谢!祝一切顺利。
djordje

2
哦,在一个实用程序做一件事并且做得很好的日子里!! sort input-file | uniq!!!!
罗恩

15

如果要使输出线与输入线的顺序相同,请使用:

$ awk '!a[$0]++' file
SO4
HOH
CL
BME

怎么运行的:

这使用关联数组a来计数先前已看到每行的次数。如果以前没有看到过,则打印该行。


2
使用,这非常棘手awk,但这sort -u是简单的方法。
皮埃尔·弗朗索瓦

4
@PierreFrançois,但这sort -u也是最慢的方法:)我已经通过两种方法之间的时间比较来更新了答案。
pa4080

4
同样,sort -u仅在输入结束后才打印结果,而此awk命令将即时打印每条新的结果行(这对于管道输入比文件更重要)。
Ruslan

感谢您的来信,@ Ruslan!我已经尝试在答案中举例说明。
pa4080

我必须承认,该awk解决方案是一个很好的解决方案,尽管它不像那样容易阅读sort
皮埃尔·弗朗索瓦(PierreFrançois)

1

您也可以在这里使用GNU datamash,如下所示,它将保持行顺序。

datamash rmdup 1 < infile

1
根据time 比较,这是此处提供的最快的解决方案。
pa4080 '18
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.