如何使用大(百万)文件数的grep来searchstring,并在几分钟内得到结果

这个问题涉及到如何有效地使用grep

我试图在一个有8-10万个小(〜2-3kb)纯文本文件的文件夹中search“string”。 我需要知道所有具有“string”的文件。

起初我用这个

grep "string" 

那太慢了。

然后我试了一下

 grep * "string" {} \; -print 

基于链接的问题,我用这个

  find . | xargs -0 -n1 -P8 grep -H "string" 

我得到这个错误:

 xargs: argument line too long 

有谁知道一个方法来完成这个任务相对更快?

我在有超过50GB可用内存的服务器机器上运行这个search,以及14个CPU核心。 我希望以某种方式使用所有的处理能力来更快地运行这个search。

您应该将xargs -0参数和-n参数删除:

 ... | xargs -n16 ... 

这不是一大堆文件(对10⁷文件的赞誉 – 一个messys的梦想),但我创建了10万个文件(总共400 MB)与

 for i in {1..100000}; do head -c 10 /dev/urandom > dummy_$i; done 

并做了一些纯粹好奇的测试(我搜索的关键词是随机选择的):

 > time find . | xargs -n1 -P8 grep -H "10" real 0m22.626s user 0m0.572s sys 0m5.800s 

 > time find . | xargs -n8 -P8 grep -H "10" real 0m3.195s user 0m0.180s sys 0m0.748s 

 > time grep "10" * real 0m0.879s user 0m0.512s sys 0m0.328s 

 > time awk '/10/' * real 0m1.123s user 0m0.760s sys 0m0.348s 

 > time sed -n '/10/p' * real 0m1.531s user 0m0.896s sys 0m0.616s 

 > time perl -ne 'print if /10/' * real 0m1.428s user 0m1.004s sys 0m0.408s 

顺便说一句。 如果我将管道STDOUT的输出压缩到/dev/null ,运行时间没有太大的差别。 我使用的是不是功能强大的笔记本电脑上的Ubuntu 12.04;)我的CPU是Intel(R)Core(TM)i3-3110M CPU @ 2.40GHz。

更好奇:

 > time find . | xargs -n1 -P8 grep -H "10" 1>/dev/null real 0m22.590s user 0m0.616s sys 0m5.876s > time find . | xargs -n4 -P8 grep -H "10" 1>/dev/null real m5.604s user 0m0.196s sys 0m1.488s > time find . | xargs -n8 -P8 grep -H "10" 1>/dev/null real 0m2.939s user 0m0.140s sys 0m0.784s > time find . | xargs -n16 -P8 grep -H "10" 1>/dev/null real 0m1.574s user 0m0.108s sys 0m0.428s > time find . | xargs -n32 -P8 grep -H "10" 1>/dev/null real 0m0.907s user 0m0.084s sys 0m0.264s > time find . | xargs -n1024 -P8 grep -H "10" 1>/dev/null real 0m0.245s user 0m0.136s sys 0m0.404s > time find . | xargs -n100000 -P8 grep -H "10" 1>/dev/null real 0m0.224s user 0m0.100s sys 0m0.520s 

一个目录中有800万个文件是很多的! 但是,2kb的800万次是16GB,你有50GB的RAM。 我正在考虑RAMdisk …

如果你有这么多的RAM,为什么不把它们全部读入内存,并使用正则表达式库来搜索? 这是一个简单的C程序:

  #include <fcntl.h> #include <regex.h> ...