【问题标题】:How to use grep efficiently?如何有效地使用 grep?
【发布时间】:2011-07-09 04:57:02
【问题描述】:

我有大量小文件要搜索。我一直在寻找一个好的事实上的多线程版本grep,但找不到任何东西。如何改进 grep 的使用?截至目前,我正在这样做:

grep -R "string" >> Strings

【问题讨论】:

    标签: linux unix search text grep


    【解决方案1】:

    如果您在多核处理器上安装了 xargs,您可以从以下内容中受益,以防有人感兴趣。

    环境:

    Processor: Dual Quad-core 2.4GHz
    Memory: 32 GB
    Number of files: 584450
    Total Size: ~ 35 GB
    

    测试:

    1.找到必要的文件,将它们传送到 xargs 并告诉它执行 8 个实例。

    time find ./ -name "*.ext" -print0 | xargs -0 -n1 -P8 grep -H "string" >> Strings_find8
    
    real    3m24.358s
    user    1m27.654s
    sys     9m40.316s
    

    2。找到必要的文件,将它们传送到 xargs 并告诉它执行 4 个实例。

    time find ./ -name "*.ext" -print0 | xargs -0 -n1 -P4 grep -H "string" >> Strings
    
    real    16m3.051s
    user    0m56.012s
    sys     8m42.540s
    

    3. @Stephen 建议:找到必要的文件并使用 + 而不是 xargs

    time find ./ -name "*.ext" -exec grep -H "string" {} \+ >> Strings
    
    real    53m45.438s
    user    0m5.829s
    sys     0m40.778s
    

    4.正则递归 grep。

    grep -R "string" >> Strings
    
    real    235m12.823s
    user    38m57.763s
    sys     38m8.301s
    

    就我的目的而言,第一个命令运行良好。

    【讨论】:

    • 我建议你使用 find 的 -print0 和 xarg 的 -0 来用 NUL 字符分隔文件名,这样你就不会因为文件名中包含空格、换行符或其他垃圾字符而遇到麻烦名字。
    • @SiegeX:+1 感谢您的指点。我已经编辑了我的答案。
    • +2 有趣的答案。干杯。 A.
    • 如果你有一个多核 CPU,你可以将 find 的输出通过管道传输到 GNU parallel 以进行并行 greping。
    • @Christian: here 是比较 xargs 和 parallel 的 GNU 并行文档的链接。
    【解决方案2】:

    想知道为什么在下面使用-n1 是不是使用更高的值会更快(比如 -n8?或者将其省略以便 xargs 会做正确的事情)?

    xargs -0 -n1 -P8 grep -H "string"
    

    似乎给每个 grep 分配处理多个文件会更有效(我假设 -n1 只会在 argv 中为 grep 提供一个文件名)——正如我所见,我们应该能够给出系统上可能的最高 n (基于argc/argv 最大长度限制)。因此,启动新 grep 进程的设置成本不会更频繁地发生。

    【讨论】:

    • 留下它不是一个好主意,因为如果find返回大量文件,这将中断,即使这没有发生,我怀疑xargs有一个很好的了解方式事先给每个 grep 实例提供多少文件。分叉的开销当然取决于文件的平均大小,一个 grep 的 n 个小文件和另一个的 n 个非常大的文件的不幸组合即使 n=2 也很容易吃掉。在我的下载目录中,我凭空选择了一个 n=64 的值,但获得了 3%。
    最近更新 更多