问题陈述: -
我需要搜索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
答案 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
会减少一些需要生成的新进程的总数。