高效搜索文本文件中的多个字符串

时间:2012-10-05 14:35:15

标签: bash grep processing-efficiency

我使用 egrep 在很长的文件中查找几个字符串的完全匹配(100万行):

egrep "\<string1\>|<\string2\>" my_file

但即使找到两个字符串也需要太多时间。它似乎沿着文件的总行查找每个字符串,即使它找到了一个匹配项。 实际上,我知道该文件只包含每个字符串的一个出现。 然后我想知道一旦发现它出现并寻找下一个列表,迫使egrep停止寻找一个字符串。或者,如果有其他方法可以有效地做到这一点。

感谢。

3 个答案:

答案 0 :(得分:2)

-m选项限制匹配数量:

-m NUM, --max-count=NUM
     Stop reading a file after NUM matching lines.

但是,你不能直接使用它的复杂模式,因为那样你只能为所有子模式获得1行。您可以做的是遍历调用fgrep -m 1的子模式:

for pat in $patterns; do
    fgrep -m 1 $pat my_file
done

P.S。另一种选择是像你一样使用复杂模式,并指定匹配数等于子模式的数量,但这会导致每个文件行的比较较慢。

答案 1 :(得分:2)

如何优化搜索取决于grep实现使用的算法。 egrep的“传统”算法是将模式编译成确定性有限自动机。如果您不知道那是什么,请不要担心:重要的是编译需要一段时间,但是一旦完成它就会非常快,而且它的速度并不依赖于它正在寻找的模式的复杂性对于。事实上,一旦编译完成,egrep实际上比fgrep更快 - 这意味着fgrep在小文件上最快,egrep在大文件上最快。

至少,这是[ef] grep的传统实现的情况。我认为大多数现代实现都是自适应的,并且将根据情况切换算法(例如,我认为现代fgreps将切换到编译的DFA模式以获得足够大的文件)。要找出实施速度最快的内容,您需要尝试一些定时实验。

我可以给你一些建议:首先,避免多次运行搜索(例如为每个单词运行fgrep),因为这意味着多次扫描文件。其次,不要担心最小化它所搜索的字符串的数量,因为如果你处于最佳模式,无论如何都无关紧要。第三,使用@Lev建议的-m使其在找到所需内容后停止(虽然我很确定只能用-m2单独搜索这两个单词。)

答案 2 :(得分:1)

我不确定,但也许这个更快:

grep -e '<pattern1>' -e '<pattern2>' -e '<pattern3>' your_file

-F也可能加快速度,我认为你的模式不是真正的模式。另外,我认为如果你的输出是彩色的,grep别无选择,只能寻找所有模式。