0

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

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

但是即使只找到两个字符串也需要太多时间。似乎它会沿着文件的总行查找每个字符串,即使它发现了一个事件。事实上,我知道该文件只包含每个字符串的一次出现。然后我想知道一旦发现字符串出现,如何强制 egrep 停止查找字符串并查找列表中的下一个。或者,如果有另一种方法可以有效地做到这一点。

谢谢。

4

3 回答 3

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

PS 另一种选择是像您一样使用复杂模式,并指定匹配数等于子模式数,但这会导致每个文件行的比较速度变慢。

于 2012-10-05T14:45:48.583 回答
2

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

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

I can give you a few recommendations, though: First, avoid running the search more than once (e.g. running fgrep for each word), because that'll mean scanning the file multiple times. Second, don't worry about minimizing the number of strings it's searching for, because if you're in the best possible mode that won't matter anyway. Third, use @Lev's suggestion of -m to make it stop after it's found what it needs to (although I'm pretty sure that'll be single search for both words with -m2).

于 2012-10-06T01:56:28.140 回答
1

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

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

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

于 2012-10-05T14:38:26.110 回答