2013-07-29 3 views
1

Каков наилучший способ с большими файлами log tar.gz, некоторые из которых - 20 гигабайт, чтобы открыть и найти ключевое слово, скопировать найденные файлы в каталог, а затем удалить файл, чтобы он не занимал дисковое пространство. У меня есть код ниже, он работал, но потом по какой-то причине он прекратил извлечение файлов. Если я удалю параметр -O из tar, он снова извлечет файлы.Поиск большого файла tar.gz для ключевых слов, копирование и удаление

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 является ключевым словом

UPDATE

Я делаю ниже, который работает, но это небольшой файл, у меня есть имеет 2million плюс сжатые файлы, так потребуется несколько часов, чтобы посмотреть на все файлы. Есть ли решение 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 " 

UPDATE 2

Im используя питон сейчас и кажется, увеличенная скорость, делает около 4000 записей второго в то время как версия Баша делает о 5.Im не так сильна в питона так вероятно, этот код можно было бы оптимизировать, пожалуйста, дайте мне знать, если это можно оптимизировать.

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() 

ответ

1

Если вы пытаетесь поиск ключевого слова в файлах и извлекать только те, и так как ваши размеры файла огромны, это может занять некоторое время, если ключевое слово находится где-то в середине.

Лучший совет, который я могу дать, вероятно, использует мощную комбинацию инструмента поиска инвертированного индекса, такого как Solr (на основе Lucene Indes) и Apache Tika - инструментарий для анализа контента.

Используя эти инструменты, вы можете проиндексировать файлы tar.gz, а при поиске ключевого слова соответствующие документы будут содержать ключевое слово.

+0

Когда я запускаю первую строку, он возвращает '-bash: -ztvf: command not found' – tsukimi

+0

Ahh! Убедитесь, что вам нужно сделать что-то вроде $ (any_commond) для запуска этого из терминала bash или, возможно, вы можете поместить команды в скрипт. –

+0

Замените ваш сценарий соответственно приведенными выше командами, где это применимо. –

1

Если файл действительно 20 ГБ, это займет очень много времени, чтобы grep в любом случае. Единственный совет, который я могу дать, - использовать zgrep. Это избавит вас от необходимости явно разжать архив.

zgrep PATTERN your.tgz 
+0

Как я могу использовать это для копирования найденных файлов в другой каталог? – tsukimi

+0

Должен признаться, что я не внимательно прочитал ваш вопрос. Чтобы cp-файлы в каталог, вам придется распаковать их. Я никогда этого не делал, но я ожидаю, что можно распаковать только пару файлов из архива, используя «tar». 'zgrep' даст вам имена файлов (внутри архива) – hek2mgl

+0

Я выполнил команду, подобную этой« zgrep »Osaka« 20130619.tar.gz', возвращает «Двоичный файл (стандартный ввод) соответствует« – tsukimi

Смежные вопросы