Как я рекурсивно ретранслировать через .gz-файлы?

Я использую скрипт для регулярной загрузки сообщений gmail, которые сжимают сырые файлы .eml в .gz. Скрипт создает папку для каждого дня, а затем сжимает каждое сообщение в свой собственный файл.

Мне нужен способ поиска в этом архиве для строки.

Похоже, что Греп не делает этого. Я также попробовал SearchMonkey.

6 Solutions collect form web for “Как я рекурсивно ретранслировать через .gz-файлы?”

Если вы хотите grep рекурсивно во всех файлах .eml.gz, вы можете использовать:

 find -name \*.eml.gz -print0 | xargs -0 zgrep "STRING" 

Вам нужно избежать первого * чтобы оболочка не интерпретировала его. -print0 сообщает find для печати нулевого символа после каждого -print0 файла; xargs -0 читает со стандартного ввода и запускает команду после него для каждого файла; zgrep работает как grep , но сначала распаковывает файл.

Здесь много путаницы, потому что не только один zgrep . У меня две версии в моей системе, zgrep от gzip и zgrep от zutils . Первый – это просто сценарий оболочки, который вызывает gzip -cdfq . Он не поддерживает -r, --recursive переключатель. 1
Последняя представляет собой c++ программу и поддерживает параметр -r, --recursive .
Запуск zgrep --version | head -n 1 zgrep --version | head -n 1 покажет, какой из них (если таковой имеется) по умолчанию:

 zgrep (gzip) 1.6 

это сценарий оболочки,

 zgrep (zutils) 1.3 

это исполняемый файл cpp .
Если у вас есть последний, вы можете запустить (как предложил Нейт):

 zgrep -r 'pattern' /path/to/dir 

Тем не менее, это будет рекурсивно grep всех файлов, сжатых или несжатых. 2 Если вы хотите grep только сжатые файлы, то find + zgrep (как предложил Джаред) будет лучшим вариантом. Он будет одинаково хорошо работать с любой версией zgrep , например:

 find /path/to/dir -name '*.gz' -exec zgrep -- 'pattern' {} + 

Обратите внимание, что с исполняемым zutils , -- не работает, поэтому, если ваш шаблон начинается с тире, вам нужно будет его избежать, например

 find /path/to/dir -name '*.gz' -exec zgrep '\-pattern' {} + 

Если zgrep отсутствует в вашей системе, вы можете попробовать:

 find /path/to/dir -name '*.gz' -exec sh -c 'gzip -cd "$0" | grep -- "pattern"' {} \; 

но есть существенный недостаток: вы не будете знать, где совпадают, так как имя файла не добавлено к соответствующим строкам.


1: поскольку это было бы проблематично
2: afaict, нет переключателя для исключения файлов, которые не сжаты. В последней бета-версии zutils (1.4-pre2) работает «-» и добавлен параметр, чтобы исключить файлы, которые не сжаты (- формат = ГЗ).

ag – вариант grep , с некоторыми приятными дополнительными функциями.

  • имеет опцию -z для сжатых файлов,
  • имеет множество функций.
  • это быстро

Так:

 ag -r -z your-pattern-goes-here folder 

Если он не установлен,

 apt-get install silversearcher-ag (debian and friends) yum install the_silver_searcher (fedora) brew install the_silver_searcher (mac) 

Рекурсия сама по себе проста:

  -r, --recursive Read all files under each directory, recursively, following symbolic links only if they are on the command line. This is equivalent to the -d recurse option. -R, --dereference-recursive Read all files under each directory, recursively. Follow all symbolic links, unlike -r. 

Однако для сжатых файлов вам нужно что-то вроде:

 shopt globstar for file in /path/to/directory/**/*gz; do zcat ""$file" | grep pattern; done 

path/to/directory должен быть родительским каталогом, который содержит подкаталоги для каждого дня.


zgrep – это очевидный ответ, но, к сожалению, он не поддерживает флаг -r . От man zgrep :

Эти параметры grep заставят zgrep завершаться с кодом ошибки: (- [d rR zZ] | –di * | –exc * | –inc * | –rec * | –nu *).

Вы должны использовать zgrep или если ваша система не имеет его:

 zcat filename | grep string 

Если ваша система имеет zgrep, вы можете просто

zgrep -irs your-pattern-goes-here the-folder-to-search-goes-here/

Если в вашей системе нет zgrep, вы можете использовать команду find для запуска zcat и grep для каждого файла:

find the-folder-to-search-goes-here/ -name '*.gz' \ -exec sh -c 'echo "Searching {}" ; zcat "{}" | grep your-pattern-goes-here ' \;

  • Как сделать grep, который исключает кучу труб?
  • Скрипт для поиска трех разных пользователей в Интернете и печати
  • извлечение строк из большого текстового файла
  • Как grep для одной строки, но несколько файлов одновременно?
  • Использует ли grep кеш для ускорения поиска?
  • grep -byte-offset не дает мне смещения байтов?
  • удалить все .swp-файл, используя команду rm
  • Проверьте, имеют ли файлы в определенном каталоге надлежащее расширение?
  • Каково влияние подчеркивания в *?
  • Греп для числа в строке
  • Получение данных под или над строкой
  • Linux и Unix - лучшая ОС в мире.