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

Posted

技术标签:

【中文标题】在文件中查找重复行并计算每行重复了多少次?【英文标题】:Find duplicate lines in a file and count how many time each line was duplicated? 【发布时间】:2011-10-06 10:43:57 【问题描述】:

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

123 
123 
234 
234 
123 
345

我想知道“123”被复制了多少次,“234”被复制了多少次,等等。 所以理想情况下,输出应该是:

123  3 
234  2 
345  1

【问题讨论】:

你想使用什么语言? 【参考方案1】:

假设每行有一个数字:

sort <file> | uniq -c

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

sort <file> | uniq --count

【讨论】:

这是我所做的,但是从算法上讲,这似乎不是最有效的方法(O(n log n)*avg_line_len,其中 n 是行数)。我正在处理几 GB 大的文件,因此性能是一个关键问题。我想知道是否有一种工具可以使用前缀树(在我的情况下,字符串通常具有公共前缀)或类似的方法在单次通过中进行计数,这应该可以在 O(n) * avg_line_len 中解决问题。有人知道这样的命令行工具吗? 另一个步骤是将其输出通过管道传输到最终的“sort -n”命令中。这将根据最常出现的行对结果进行排序。 如果你只想打印重复的行,使用'uniq -d' 如果您想再次对结果进行排序,您可以再次使用sort,例如:sort &lt;file&gt; | uniq -c | sort -n 如果没有提到@DmitrySandalov 帽子-d 我会选择… | uniq -c | grep -v '^\s*1' -v 表示反正则表达式,它拒绝匹配(不冗长,不是版本:))【参考方案2】:

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

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

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

【讨论】:

我猜这个解决方案是针对您自己的特定情况量身定制的?即您有一个仅由空格或换行符分隔的单词列表。如果它只是一个由换行符(没有空格)分隔的数字列表,它会在那里正常工作,但显然你的解决方案会以不同的方式处理包含空格的行。【参考方案3】:

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

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

或:

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

【讨论】:

【参考方案4】:

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

sort FILE | uniq -cd

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

sort FILE | uniq --count --repeated

在BSD and OSX you have to use 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

【讨论】:

使用 --repeated 或 -d 选项很好。比使用“|grep 2”或类似的更准确! 如何修改此命令以检索所有重复次数超过 100 的行? @Black_Rider 将| sort -n| sort -nr 添加到管道将按重复计数(分别为升序或降序)对输出进行排序。这不是您要问的,但我认为它可能会有所帮助。 @Black_Rider awk 似乎能够进行各种计算:在您的情况下,您可以进行 | awk '$1&gt;100' @fionbio 看起来像you can't use -c and -d together on OSX uniq。感谢您指出。你可以use grep to filter out unique lines:sort FILE | uniq -c | grep -v '^ *1 '【参考方案5】:

通过awk:

awk 'dups[$1]++ ENDfor (num in dups) print num,dups[num]' data

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

最后,我们以num 为变量循环遍历dups 数组,并首先打印保存的数字,然后打印它们的重复值的数量dups[num]

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

【讨论】:

考虑到我们有uniq,这不是有点矫枉过正吗? sort | uniq 和 awk 解决方案在性能和资源权衡方面有很大不同:如果文件很大并且不同的行数很少,则 awk 解决方案的效率要高得多。它与行数成线性关系,空间使用与不同行数成线性关系。 OTOH,awk 解决方案需要将所有不同的行保存在内存中,而(GNU)排序可以诉诸临时文件。【参考方案6】:

在windows中使用“Windows PowerShell”我使用下面提到的命令来实现这个

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

【讨论】:

你能删除除最后一个之外的所有重复项...而不更改文件的排序顺序吗?【参考方案7】:

要查找重复计数,请按照您的要求使用以下命令:

sort filename | uniq -c | awk 'print $2, $1'

【讨论】:

以上是关于在文件中查找重复行并计算每行重复了多少次?的主要内容,如果未能解决你的问题,请参考以下文章

从 CSV 中随机选择行并重复 X 次

在文本文件中查找特定单词并计算它

如何删除唯一行并保持重复? SQL

Oracle SQL - 重复行并更新表中的列

刷题面筋-shell:统计一个文件中重复的行和重复次数

刷题面筋-shell:统计一个文件中重复的行和重复次数