我有一个很大的 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
命令,因为它很简单,但如果你使用大型数组,那么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
sort -u
仅在输入结束后才会打印结果,而此awk
命令将动态打印每个新的结果行(这对于管道输入可能比文件更重要)。
以下是一个例子:
在上面的例子中,循环(如下所示)生成 500 个字母 AD 的随机组合,每个组合的长度为三个字符。这些组合通过管道传输到awk
或sort
。
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