最快的grep

时间:2012-01-30 15:50:43

标签: bash unix grep

我想知道是否有任何提示尽快使 grep 。我有一个相当大的文本文件库,以最快的方式搜索。我把它们全都小写了,这样我就可以摆脱-i选项了。这使搜索速度更快。

另外,我发现-F-P模式比默认模式更快。当搜索字符串不是正则表达式(只是纯文本)时,我使用前者,后者如果涉及正则表达式。

有没有人有加快grep的经验?也许用一些特定的标志从头开始编译(我在Linux CentOS上),以某种方式组织文件或者以某种方式使搜索并行?

12 个答案:

答案 0 :(得分:104)

尝试使用GNU parallel,其中包括an example of how to use it with grep

  

grep -r递归遍历目录。在多核CPU GNU上   parallel通常可以加快速度。

find . -type f | parallel -k -j150% -n 1000 -m grep -H -n STRING {}
     

这将为每个核心运行1.5个作业,并为grep提供1000个参数。

对于大文件,它可以使用--pipe--block参数将输入拆分为多个块:

 parallel --pipe --block 2M grep foo < bigfile

你也可以通过SSH在几台不同的机器上运行它(ssh-agent需要避免密码):

parallel --pipe --sshlogin server.example.com,server2.example.net grep foo < bigfile

答案 1 :(得分:70)

如果您正在搜索非常大的文件,那么设置您的语言环境确实可以提供帮助。

GNU grep在C语言环境中的速度比使用UTF-8快得多。

export LC_ALL=C

答案 2 :(得分:12)

Ripgrep声称现在是最快的。

https://github.com/BurntSushi/ripgrep

默认情况下还包括并行性

 -j, --threads ARG
              The number of threads to use.  Defaults to the number of logical CPUs (capped at 6).  [default: 0]

来自自述文件

  

它建立在Rust的正则表达式引擎之上。 Rust的正则表达式引擎使用   有限自动机,SIMD和积极的文字优化   快速搜索。

答案 3 :(得分:5)

显然使用--mmap可以在某些系统上提供帮助:

http://lists.freebsd.org/pipermail/freebsd-current/2010-August/019310.html

答案 4 :(得分:4)

不是严格意义上的代码改进,而是我在200万个文件上运行grep后发现有用的东西。

我将操作移到便宜的SSD驱动器(120GB)上。大约100美元,如果你经常处理大量文件,这是一个经济实惠的选择。

答案 5 :(得分:3)

如果您不关心哪些文件包含字符串,您可能希望将阅读 grepping 分成两个作业,因为生成{可能代价高昂} {1}}多次 - 每个小文件一次。

  1. 如果您有一个非常大的文件:

    grep

  2. 许多小型压缩文件(按inode排序)

    parallel -j100% --pipepart --block 100M -a <very large SEEKABLE file> grep <...>

  3. 我通常使用lz4压缩文件以获得最大吞吐量。

    1. 如果您只想要匹配的文件名:

      ls -i | sort -n | cut -d' ' -f2 | fgrep \.gz | parallel -j80% --group "gzcat {}" | parallel -j50% --pipe --round-robin -u -N1000 grep <..>

答案 6 :(得分:2)

在桑德罗的回应基础上,我查看了他提供的参考文献here并使用了BSD grep与GNU grep。我的快速基准测试结果显示:GNU grep方式更快。<​​/ p>

所以我建议原始问题“尽可能快的grep”:确保你使用的是GNU grep而不是BSD grep(例如MacOS上的默认设置)。

答案 7 :(得分:2)

我个人使用ag(银色搜索器)代替grep,它的速度更快,你也可以将它与平行和管道组合使用。

https://github.com/ggreer/the_silver_searcher

更新: 我现在使用的https://github.com/BurntSushi/ripgrep比ag更快,具体取决于你的用例。

答案 8 :(得分:1)

我发现使用grep在单个大文件中搜索(尤其是更改模式)更快的一件事是使用split + grep + xargs和它的并行标志。例如:

在一个名为my_ids.txt的大文件中找到要搜索的ID文件 bigfile名称bigfile.txt

使用拆分将文件拆分为多个部分:

# Use split to split the file into x number of files, consider your big file
# size and try to stay under 26 split files to keep the filenames 
# easy from split (xa[a-z]), in my example I have 10 million rows in bigfile
split -l 1000000 bigfile.txt
# Produces output files named xa[a-t]

# Now use split files + xargs to iterate and launch parallel greps with output
for id in $(cat my_ids.txt) ; do ls xa* | xargs -n 1 -P 20 grep $id >> matches.txt ; done
# Here you can tune your parallel greps with -P, in my case I am being greedy
# Also be aware that there's no point in allocating more greps than x files

就我而言,这可以将17小时的工作减少到1小时20分钟的工作。我确信这里有一些关于效率的钟形曲线,显然超过可用内核对你没有任何好处,但对于我上面提到的要求,这是一个比上述任何评论更好的解决方案。与使用大多数(linux)本机工具并行的脚本相比,这有一个额外的好处。

答案 9 :(得分:0)

cgrep,如果它可用,可以比grep快几个数量级。

答案 10 :(得分:0)

MCE 1.508包含支持许多C二进制文件的双块级{file,list}包装脚本; agrep,grep,egrep,fgrep和tre-agrep。

https://metacpan.org/source/MARIOROY/MCE-1.509/bin/mce_grep

https://metacpan.org/release/MCE

当想要-i快速运行时,不需要转换为小写。只需将--lang = C传递给mce_grep。

保留输出顺序。 -n和-b输出也是正确的。不幸的是,本页提到的GNU并行不是这种情况。我真的希望GNU Parallel能够在这里工作。另外,调用二进制文件时,mce_grep执行 not 子shell(sh -c / path / to / grep)。

另一个替代方案是MCE附带的MCE :: Grep模块。

答案 11 :(得分:0)

与原始主题稍有不同:googlecodesearch项目中的索引搜索命令行实用程序比grep:https://github.com/google/codesearch更快:

编译后(需要golang包),您可以使用以下文件索引文件夹:

# index current folder
cindex .

索引将在~/.csearchindex

下创建

现在你可以搜索:

# search folders previously indexed with cindex
csearch eggs

我仍然通过grep管道结果以获得彩色匹配。