найти строку внутри сжатого файла в папке - PullRequest
43 голосов
/ 10 августа 2009

Моя текущая проблема заключается в том, что у меня есть около 10 папок, которые содержат сжатые файлы (в среднем по 5 в каждой). Это позволяет открывать и просматривать 50 файлов.

Есть ли более простой способ выяснить, имеет ли файл gzip внутри папки определенный шаблон или нет?

zcat ABC/myzippedfile1.txt.gz | grep "pattern match"
zcat ABC/myzippedfile2.txt.gz | grep "pattern match"

Вместо написания скрипта, могу ли я сделать то же самое в одной строке для всех папок и подпапок?

for f in `ls *.gz`; do echo $f; zcat $f | grep <pattern>; done;

Ответы [ 7 ]

49 голосов
/ 10 августа 2009

zgrep будет искать в gzip-файлах, имеет рекурсивную опцию -R, а -H покажет мне опцию имени файла:

zgrep -R --include=*.gz -H "pattern match" .
20 голосов
/ 10 августа 2009

Вам не нужно zcat здесь, потому что есть zgrep и zegrep.

Если вы хотите запустить команду в иерархии каталогов, вы используете find:

find . -name "*.gz" -exec zgrep ⟨pattern⟩ \{\} \;

А также «ls *.gz» бесполезен в для , и вы должны просто использовать «* .gz» в будущем.

8 голосов
/ 28 марта 2012

как zgrep не поддерживает -R

Я думаю, что решение "Nietzche-jou" могло бы быть лучшим ответом, но я бы добавил опцию -H, чтобы показать имя файла примерно так

find . -name "*.gz" -exec zgrep -H 'PATTERN' \{\} \;
7 голосов
/ 10 августа 2009

используйте команду поиска

find . -name "*.gz" -exec zcat "{}" + |grep "test"

или попробуйте использовать рекурсивную опцию (-r) zcat

6 голосов
/ 09 октября 2013

Пришел немного позже, имел аналогичную проблему и смог решить с помощью;

zcat -r /some/dir/here | grep "blah"

Как подробно здесь;

http://manpages.ubuntu.com/manpages/quantal/man1/gzip.1.html

Однако, это не показывает исходный файл, из которого был получен результат, а вместо этого показывает "(стандартный ввод)", поскольку он поступает из канала. zcat, похоже, также не поддерживает вывод имени.

С точки зрения производительности, это то, что мы получили;

$ alias dropcache="sync && echo 3 > /proc/sys/vm/drop_caches"

$ find 09/01 | wc -l
4208

$ du -chs 09/01
24M

$ dropcache; time zcat -r 09/01 > /dev/null
real    0m3.561s

$ dropcache; time find 09/01 -iname '*.txt.gz' -exec zcat '{}' \; > /dev/null
0m38.041s

Как видите, использование метода find|zcat значительно медленнее, чем использование zcat -r при работе даже с небольшим объемом файлов. Мне также не удалось заставить zcat вывести имя файла (с помощью -v, очевидно, будет выводиться имя файла, но не в каждой строке). Может показаться, что в настоящее время не существует инструмента, который обеспечивал бы согласованность как по скорости, так и по имени с помощью grep (то есть опция -H).

Если вам нужно определить имя файла, к которому относится результат, вам нужно будет либо написать свой собственный инструмент (это можно сделать из 50 строк кода Python), либо использовать более медленный метод. Если вам не нужно указывать имя, используйте zcat -r.

Надеюсь, это поможет

2 голосов
/ 26 ноября 2013

find . -name "*.gz"|xargs zcat | grep "pattern" должен сделать.

1 голос
/ 07 сентября 2018

zgrep "string" ./*/*

Вы можете использовать указанную выше команду для поиска string в файлах .gz каталога dir, где dir имеет следующую структуру подкаталогов:

/dir
    /childDir1
              /file1.gz
              /file2.gz
    /childDir2
              /file3.gz
              /file4.gz
    /childDir3
              /file5.gz
              /file6.gz
...