在文件中查找重复行并计算每行重复了多少次?
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 <file> | 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>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'
【讨论】:
以上是关于在文件中查找重复行并计算每行重复了多少次?的主要内容,如果未能解决你的问题,请参考以下文章