我想知道是否有任何提示尽快使 grep
。我有一个相当大的文本文件库,以最快的方式搜索。我把它们全都小写了,这样我就可以摆脱-i
选项了。这使搜索速度更快。
另外,我发现-F
和-P
模式比默认模式更快。当搜索字符串不是正则表达式(只是纯文本)时,我使用前者,后者如果涉及正则表达式。
有没有人有加快grep
的经验?也许用一些特定的标志从头开始编译(我在Linux CentOS上),以某种方式组织文件或者以某种方式使搜索并行?
答案 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}}多次 - 每个小文件一次。
如果您有一个非常大的文件:
grep
许多小型压缩文件(按inode排序)
parallel -j100% --pipepart --block 100M -a <very large SEEKABLE file> grep <...>
我通常使用lz4压缩文件以获得最大吞吐量。
如果您只想要匹配的文件名:
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管道结果以获得彩色匹配。