我想知道是否有任何提示可以使您grep
尽快完成。我有大量的文本文件,可以以最快的方式进行搜索。我把它们都改成小写,这样我就可以摆脱-i
选择了。这样可以使搜索更快。
另外,我发现-F
and-P
模式比默认模式更快。如果搜索字符串不是正则表达式(仅是纯文本),则使用前者;如果涉及到正则表达式,则使用后者。
有没有人有加速的经验grep
?也许使用某些特定标志从头开始编译它(我在Linux CentOS上),以某种方式组织文件,或者以某种方式使搜索并行化?
我想知道是否有任何提示可以使您grep
尽快完成。我有大量的文本文件,可以以最快的方式进行搜索。我把它们都改成小写,这样我就可以摆脱-i
选择了。这样可以使搜索更快。
另外,我发现-F
and-P
模式比默认模式更快。如果搜索字符串不是正则表达式(仅是纯文本),则使用前者;如果涉及到正则表达式,则使用后者。
有没有人有加速的经验grep
?也许使用某些特定标志从头开始编译它(我在Linux CentOS上),以某种方式组织文件,或者以某种方式使搜索并行化?
"...or maybe make the search parallel in some way?"
听到这个消息,我会感到非常兴奋。 grep
应该完全能够并行运行,但是我怀疑搜索可能仍然受I / O约束。
ack-grep
?
ack-grep
或更好的银!geoff.greer.fm/2011/12/27/the-silver-searcher-better-than-ack
Answers:
尝试使用GNU parallel,其中包括如何grep
与GNU parallel一起使用的示例:
grep -r
通过目录递归浏览。在多核CPU上,GNUparallel
通常可以加快速度。
find . -type f | parallel -k -j150% -n 1000 -m grep -H -n STRING {}
每个内核将运行1.5个作业,并为分配1000个参数
grep
。
对于大文件,它可以使用--pipe
和--block
参数将输入分为几个块:
parallel --pipe --block 2M grep foo < bigfile
您还可以通过SSH(需要避免密码的ssh-agent)在几台不同的计算机上运行它:
parallel --pipe --sshlogin server.example.com,server2.example.net grep foo < bigfile
--color=always
保留grep颜色(在管道中也使用grep时也是如此)
find
具有-print0
谓词(大多数情况),则最好使用find . -type f -print0 | parallel -0 -k …
。我的实例man(1) parallel
实际上是这样说的。另外,我怀疑globstar
如果您shopt -s globstar; parallel -k -j150% -n 1000 -m fgrep -H -n STRING ::: **/*.c
cat
,如果你想sudo
访问bigfile
如果要搜索非常大的文件,那么设置区域设置确实可以提供帮助。
GNU grep在C语言环境中的运行速度比使用UTF-8快得多。
export LC_ALL=C
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的regex引擎之上。Rust的regex引擎使用有限自动机,SIMD和积极的文字优化来使搜索变得非常快。
显然,使用--mmap可以在某些系统上提供帮助:
http://lists.freebsd.org/pipermail/freebsd-current/2010-August/019310.html
如果您不关心哪个文件包含该字符串,则可能需要将读取和grepping分为两个作业,因为生成grep
很多次可能会很昂贵-每个小文件一次。
如果您有一个非常大的文件:
parallel -j100% --pipepart --block 100M -a <very large SEEKABLE file> grep <...>
许多小的压缩文件(按inode排序)
ls -i | sort -n | cut -d' ' -f2 | fgrep \.gz | parallel -j80% --group "gzcat {}" | parallel -j50% --pipe --round-robin -u -N1000 grep <..>
我通常使用lz4压缩文件以实现最大吞吐量。
如果只需要匹配的文件名:
ls -i | sort -n | cut -d' ' -f2 | fgrep \.gz | parallel -j100% --group "gzcat {} | grep -lq <..> && echo {}
我个人使用ag(silver searcher)代替grep,它的运行速度更快,您也可以将其与并行和管道块结合使用。
https://github.com/ggreer/the_silver_searcher
更新:我现在使用https://github.com/BurntSushi/ripgrep,它比ag快,具体取决于您的用例。
我发现在单个大文件中使用grep进行搜索(尤其是更改模式)的速度更快,是使用split + grep + xargs及其并行标志。例如:
在一个名为my_ids.txt的大文件中有一个要搜索的id文件,bigfile的名称bigfile.txt
使用split将文件拆分为多个部分:
# 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)本机工具的脚本并行处理相比,这具有更多的好处。
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 parallel并非如此。我真的希望GNU Parallel在这里工作。此外,mce_grep确实未子壳(SH -c /路径/到/ grep)来调用二进制时。
另一个替代方案是MCE附带的MCE :: Grep模块。
与原始主题略有不同:googlecodesearch项目中的索引搜索命令行实用程序比grep快得多:https : //github.com/google/codesearch:
编译后(需要golang包),您可以使用以下方法索引文件夹:
# index current folder
cindex .
索引将在 ~/.csearchindex
现在您可以搜索:
# search folders previously indexed with cindex
csearch eggs
我仍然通过grep传递结果以获取彩色匹配。
grep
,也许是时候寻找一种解决方案来对它们进行正确索引了(“最佳”解决方案取决于这些文件是哪种文件)。