使用大型日志tar.gz文件(有些是20 gig)的最佳方法是打开并搜索关键字,将找到的文件复制到目录,然后删除文件以便不占用磁盘空间。 我下面有一些代码,它正在工作,但由于某种原因它突然停止提取文件。如果我从tar中删除-O选项,它会再次提取文件。
mkdir -p found;
tar tf "$1" | while read -r FILE
do
if tar xf "$1" "$FILE" -O | grep -l "$2" ;then
echo "found pattern in : $FILE";
cp $FILE found/$(basename $FILE);
rm -f $FILE;
fi
done
$ 1是tar.gz文件,$ 2是关键字
更新
我正在做下面的工作,但我有一个小文件有200万加压缩文件,所以需要几个小时来查看所有文件。有一个python解决方案或类似的,可以更快地做到。
#!/bin/sh
# tarmatch.sh
if grep -l "$1" ; then
echo "Found keyword in ${TAR_FILENAME}";
tar -zxvf "$2" "${TAR_FILENAME}"
else
echo "Not found in ${TAR_FILENAME}";
fi
true
tar -zxf 20130619.tar.gz --to-command "./tarmatch.sh '@gmail' 20130619.tar.gz "
更新2
我现在正在使用python并且似乎速度有所提高,每秒做大约4000条记录,而bash版本正在做大约5.我在python中没有那么强大所以可能这个代码可以优化,请告诉我是否这可以进行优化。
import tarfile
import time
import os
import ntpath, sys
if len(sys.argv) < 3 :
print "Please provide the tar.gz file and keyword to search on"
print "USAGE: tarfind.py example.tar.gz keyword"
sys.exit()
t = tarfile.open(sys.argv[1], 'r:gz')
cnt = 0;
foundCnt = 0;
now = time.time()
directory = 'found/'
if not os.path.exists(directory):
os.makedirs(directory)
for tar_info in t:
cnt+=1;
if (tar_info.isdir()): continue
if(cnt%1000 == 0): print "Processed " + str(cnt) + " files"
f=t.extractfile(tar_info)
if sys.argv[2] in f.read():
foundCnt +=1
newFile = open(directory + ntpath.basename(tar_info.name), 'w');
f.seek(0,0)
newFile.write( f.read() )
newFile.close()
print "found in file " + tar_info.name
future = time.time()
timeTaken = future-now
print "Found " + str(foundCnt) + " records"
print "Time taken " + str( int( timeTaken/60) ) + " mins " + str(int(timeTaken%60)) + " seconds"
print str( int(cnt / timeTaken)) + " records per second"
t.close()
答案 0 :(得分:1)
如果文件真的是20GB,那么在任何情况下grep都需要很长时间。我可以给出的唯一建议是使用zgrep
。这将使您不必显式解压缩存档。
zgrep PATTERN your.tgz
答案 1 :(得分:1)
如果您尝试在文件中搜索关键字并仅提取这些关键字,并且由于文件大小很大,如果关键字位于中间位置,则可能需要一些时间。
我能给出的最好的建议可能是使用倒置索引查找工具的强大组合,例如Solr(基于Lucene Indes)和Apache Tika - 内容分析工具包。
使用这些工具可以索引tar.gz文件,当您搜索关键字时,将返回包含该关键字的相关文档。