【问题标题】:grep: count all matches to all patternsgrep:计算所有模式的所有匹配项
【发布时间】:2011-10-20 18:53:28
【问题描述】:

我有数以万计的(固定的)模式,我想在一个非常大的文件中找到它们的匹配项。我想计算每个模式的命中总数。我在 grep 文档中找不到任何表明这是可能的内容。我的设置如下所示:

gunzip -c bigfile.txt.gz | grep -c -f patterns.txt

当然,这会计算与patterns.txt 中的 anything 匹配的行,而我想要的是每个模式的单独命中数。使用 grep 可以在命令行上执行类似的操作吗?还是我必须写一个程序?

【问题讨论】:

  • 您确定grep -f patterns.txt 可以加载数千种模式吗?我的经验是在 patterns.txt 中的 2048 行文本之后,我必须找到 grep 的 src 代码并修改以增加搜索列表大小。 (这是在 2000 年代中期的 solaris 下,但我认为当时我在 gnu utils 上遇到了类似的问题)。祝你好运。

标签: linux command-line grep


【解决方案1】:

我不知道要同时为所有模式执行此操作,但您可以编写一个 bash 脚本,一次读取一个并执行 grep | wc -l 每个。

【讨论】:

  • 将花费 N 倍的时间,其中 N 已由 OP 指定为数千。祝大家好运。
  • 会的。这是一个可能的选择,遗憾的是我想不出更好的选择。
【解决方案2】:

这样的事情怎么样:

gunzip -c bigfile.txt.gz | grep -f patterns.txt | sort | uniq -c

排序可能有点大,因为它会保存整个输出。不过,带有哈希的快速 perl/python/... 脚本可以大大减少这种情况。

$ grep -f pats.txt a.txt  | ./t.rb 
a 3
b 3
c 2

这是避免排序的脚本,看看它是否真的加快了速度。

#!/usr/bin/env ruby
results = {}
while gets
  line = $_.chomp
  results[line] ||= 0
  results[line]+= 1
end
results.each { |k,v| puts ""#{k} #{v}"}

【讨论】:

  • 当我执行grep -f patterns.txt a.txt | ./t.rb 时,我得到./t.rb:8: syntax error, unexpected $end, expecting '}'。我对红宝石一无所知,所以我无法调试它。我逐渐开始认为更大的问题是 grep 不适合我想做的事情。它是为寻找一个或几个模式而设计的,而不是我感兴趣的数以万计的模式。我猜是时候整理一下我的 C 技能并编写一个小程序了。无论如何感谢您的建议。
猜你喜欢
  • 1970-01-01
  • 2021-10-27
  • 2012-05-18
  • 1970-01-01
  • 2014-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多