并行搜索10000个文件中的特定字符串模式

时间:2012-08-15 23:30:24

标签: linux bash grep solaris sunos

问题陈述: -

我需要搜索String Pattern周围的特定10000 files,并在包含该particular pattern的文件中查找记录。我可以在这里使用grep,但这需要花费很多时间。

以下是particular string pattern unzipping之后用于搜索dat.gz file的命令

gzcat /data/newfolder/real-time-newdata/*_20120809_0_*.gz | grep 'b295ed051380a47a2f65fb75ff0d7aa7^]3^]-1'

如果我只是在解压缩上述dat.gz file

后计算出有多少文件
gzcat /data/newfolder/real-time-newdata/*_20120809_0_*.gz | wc -l

我绕过10000 files。我需要在所有这些10000 files中搜索上面的字符串模式,并找出包含上述String Pattern的记录。我的上述命令工作正常,但速度非常慢。

这方面最好的方法是什么?我们是否应该一次100 files并在100 files parallelly中搜索特定的字符串模式。

注意:

我正在运行 SunOS

bash-3.00$ uname -a
SunOS lvsaishdc3in0001 5.10 Generic_142901-02 i86pc i386 i86pc

4 个答案:

答案 0 :(得分:2)

NOT 并行运行!!!!这将会在整个地方反弹磁盘头,速度会慢得多。

由于您正在阅读存档文件,因此有一种方法可以大幅提升性能 - 不要将解压缩的结果写出来。理想的答案是解压缩到内存中的流,如果那不可行,那么解压缩到ramdisk。

在任何情况下,你确实需要一些并行性 - 一个线程应该获取数据然后将其交给另一个执行搜索的数据。这样你就可以在磁盘上或核心上等待解压缩,你不会浪费任何时间进行搜索。

(请注意,在ramdisk的情况下,你会想要积极地读取它写的文件,然后杀死它们,这样ramdisk就不会填满。)

答案 1 :(得分:0)

对于初学者,您需要将文件解压缩到磁盘。

这确实有效(在bash中),但您可能不想尝试一次启动10,000个进程。在未压缩的目录中运行它:

for i in `find . -type f`; do ((grep 'b295ed051380a47a2f65fb75ff0d7aa7^]3^]-1' $i )&); done

因此,我们需要一种方法来限制衍生进程的数量。只要机器上运行的grep进程数超过10(包括进行计数的进程),这就会循环:

while [ `top -b -n1 | grep -c grep` -gt 10  ]; do echo true; done

我已经运行了它,并且它可以工作....但是top需要很长时间才能运行它有效地限制你每秒一个grep。有人可以对此进行改进,在新进程启动时向计数添加一个,在进程结束时减1;

for i in `find . -type f`; do ((grep -l 'blah' $i)&); (while [ `top -b -n1 | grep -c grep` -gt 10 ]; do sleep 1; done); done

关于如何确定何时入睡以及何时不去的任何其他想法?对于部分解决方案感到抱歉,但我希望有人能够满足您的需求。

答案 2 :(得分:0)

如果您不使用正则表达式,可以使用grep的-F选项或使用fgrep。这可能会为您提供额外的表现。

答案 3 :(得分:0)

你的gzcat .... | wc -l并不表示10000个文件,它表示总共10000行,但是有很多文件。

这是xargs存在的问题类型。假设您的gzip版本附带了一个名为gzgrep的脚本(或者只是zgrep),您可以这样做:

find /data/newfolder/real-time-newdata -type f -name "*_20120809_0_*.gz" -print | xargs gzgrep

这将运行一个gzgrep命令,其中包含尽可能多的单个文件,这些文件可以放在命令行上(xargs可以选择限制多少,或者用于其他一些东西)。不幸的是,gzgrep仍然必须解压缩每个文件并将其传递给grep,但实际上没有任何好的方法可以避免解压缩整个语料库以便搜索它。但是,以这种方式使用xargs会减少一些需要生成的新进程的总数。