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

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

我有一个很大的 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 

问题是我有大量不同的值,所以无法像这里一样手动进行。

答案1

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

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

怎么运行的:

它使用关联数组a来计算每行之前出现的次数。如果之前没有出现过,则打印该行。

答案2

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命令,因为它很简单,但如果你使用大型数组,那么awkJohn1024 的方法回答可能会更强大。以下是上述方法对一个包含近 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命令将动态打印每个新的结果行(这对于管道输入可能比文件更重要)。

以下是一个例子:

在此处输入图片描述

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

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

答案3

您可以使用GNU datamash这里也同样如下,并且会保持行序。

datamash rmdup 1 < infile

相关内容