在大型数据集上使用grep或fgrep进行非常慢的循环

jks*_*ksl 6 bash grep loops

我正在尝试做一些非常简单的事情; 来自列表的grep,对于字符串的完全匹配,对目录中的文件:

#try grep each line from the files
for i in $(cat /data/datafile); do 
LOOK=$(echo $i);
fgrep -r $LOOK /data/filestosearch >>/data/output.txt
done
Run Code Online (Sandbox Code Playgroud)

与grep相匹配的文件有2000万行,目录有大约600个文件,总共有大约40万行我可以看到这将是缓慢但我们估计需要7年.即使我在HPC上使用300个内核按文件分割作业进行搜索,看起来可能需要一周时间.

有类似的问题:

循环运行很慢 :

非常缓慢的foreach循环

虽然它们位于不同的平台上,但我想可能还有其他可能对我有所帮助.或fgrep可能更快(但我现在正在测试它似乎有点慢)任何人都可以看到更快的方法吗?先感谢您

Mar*_*tin 5

听起来像是适合这里的-f旗帜grep:

-f FILE, --file=FILE
    Obtain  patterns  from  FILE,  one  per  line.   The  empty file
    contains zero patterns, and therefore matches nothing.   (-f  is
    specified by POSIX.)
Run Code Online (Sandbox Code Playgroud)

所以grep可以做你的循环正在做的事情,你可以用以下代码替换循环:

grep -F -r -f /data/datafile /data/filestosearch >>/data/output.txt
Run Code Online (Sandbox Code Playgroud)

现在我不确定2000万个模式的性能,但至少你没有以这种方式启动2000万个进程,所以它可能要快得多.


Igo*_*bin 0

您可以编写 perl/python 脚本,它将为您完成这项工作。当您使用外部工具执行此操作时,它会保存您需要执行的所有分叉操作。

另一个提示:您可以将要查找的字符串组合到一个正则表达式中。在这种情况下,grep 只会对所有组合行执行一次。

例子:

代替

for i in ABC DEF GHI JKL
do
grep $i file >> results
done
Run Code Online (Sandbox Code Playgroud)

你可以做

egrep "ABC|DEF|GHI|JKL" file >> results
Run Code Online (Sandbox Code Playgroud)