在文件中查找重复的行并计算每行重复多少次?


529

假设我有一个类似于以下文件:

123 
123 
234 
234 
123 
345

我想查找重复的次数“ 123”,重复的次数“ 234”,等等。因此,理想情况下,输出如下:

123  3 
234  2 
345  1

4
您要使用哪种语言?
VMAtm 2011年

Answers:


791

假设每行有一个数字:

sort <file> | uniq -c

您也可以--count在GNU版本中使用更详细的标志,例如在Linux上:

sort <file> | uniq --count

3
这是我要做的,但是在算法上,这似乎并不是最有效的方法(O(n log n)* avg_line_len,其中n是行数)。我正在处理几GB的文件,因此性能是关键问题。我想知道是否有一种工具可以使用前缀树(在我的情况下,字符串通常具有共同的前缀)或类似方法一次完成一次计数,所以应该在O(n)* avg_line_len中做到这一点。有谁知道这样的命令行工具?
Droggl

21
另一个步骤是将其输出传递到最终的“ sort -n”命令中。这将对行最常出现的结果进行排序。
samoz 2014年

79
如果你想只打印重复的行,用“uniq的-d”
DmitrySandalov

6
如果您想再次对结果进行排序,则可以sort像这样再次使用:sort <file> | uniq -c | sort -n
Abhishek Kashyap

413

这将仅打印重复的行,计数:

sort FILE | uniq -cd

或者,使用GNU长选项(在Linux上):

sort FILE | uniq --count --repeated

BSD和OSX上,您必须使用grep过滤出唯一的行:

sort FILE | uniq -c | grep -v '^ *1 '

对于给定的示例,结果将是:

  3 123
  2 234

如果要打印所有行的计数,包括仅出现一次的行:

sort FILE | uniq -c

或者,使用GNU长选项(在Linux上):

sort FILE | uniq --count

对于给定的输入,输出为:

  3 123
  2 234
  1 345

为了对最上面的行最频繁的输出进行排序,您可以执行以下操作(获取所有结果):

sort FILE | uniq -c | sort -nr

或者,仅重复行,最频繁出现

sort FILE | uniq -cd | sort -nr

在OSX和BSD上,最后一个变为:

sort FILE | uniq -c | grep -v '^ *1 ' | sort -nr

1
使用--repeated或-d选项很好。比使用“ | grep 2”或类似的东西要准确得多!
劳里

如何修改此命令以检索重复计数大于100的所有行?
Black_Rider

@Black_Rider 在管道中添加| sort -n| sort -nr将按重复计数(分别为升序或降序)对输出进行排序。这不是您要的内容,但我认为可能会有所帮助。
Andrea

1
@Black_Rider awk似乎能够执行所有类型的计算:就您而言,您可以这样做| awk '$1>100'
Andrea

4
@fionbio看来您不能在OSX uniq上同时使用-c和-d。感谢您指出。您可以使用grep过滤出唯一的行sort FILE | uniq -c | grep -v '^ *1 '
Andrea'1

72

要查找和计数多个文件中的重复行,可以尝试以下命令:

sort <files> | uniq -c | sort -nr

要么:

cat <files> | sort | uniq -c | sort -nr

30

通过

awk '{dups[$1]++} END{for (num in dups) {print num,dups[num]}}' data

awk 'dups[$1]++'命令中,变量$1保存column1的全部内容,方括号是数组访问权限。因此,对于文件中每一行的第一列,data命名数组的节点dups都会增加。

最后,我们dups使用numas变量遍历数组,并先打印保存的数字,然后打印重复值的数字dups[num]

请注意,您的输入文件在某些​​行的末尾有空格,如果您将其清除,则可以$0代替$1上面的in命令使用:)


1
考虑到我们有,这难道不是有点过分了uniq吗?
弥敦道·费尔曼

9
sort | uniq与awk解决方案在性能和资源折衷方面有很大不同:如果文件很大且行数较少,则awk解决方案效率更高。行数是线性的,空间使用量是不同行数的线性。OTOH,awk解决方案需要将所有不同的行保留在内存中,而(GNU)排序可以求助于临时文件。
Lars Noschinski

14

在使用“ Windows PowerShell”的Windows中,我使用下面提到的命令来实现此目的

Get-Content .\file.txt | Group-Object | Select Name, Count

我们也可以使用where-object Cmdlet过滤结果

Get-Content .\file.txt | Group-Object | Where-Object { $_.Count -gt 1 } | Select Name, Count

您可以删除除上一个重复项以外的所有重复项...而无需更改文件的排序顺序吗?
jparram

6

假设您可以访问标准的Unix shell和/或cygwin环境:

tr -s ' ' '\n' < yourfile | sort | uniq -d -c
       ^--space char

基本上:将所有空格字符转换为换行符,然后对翻译后的输出进行排序,并将其提供给uniq并计算重复行。

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.