8

Как я могу grep для строки рекурсивно через все файлы .gz во всех каталогах и подкаталогах?

4 ответа4

13

@ Steve Weet почти там. Использование /dev /null в качестве дополнительного аргумента является хорошим способом заставить имя файла отображаться (я буду помнить это, спасибо Стиву), но он все равно запускает exec для каждого найденного файла - огромные накладные расходы.

Вы хотите запускать zgrep как можно меньше раз, получая максимальную отдачу от каждого выполнения:

find . -iname '*.gz' -print0 | xargs -0 zgrep PATTERN

xargs предоставит zgrep столько аргументов (имен файлов), сколько возможно, и будет повторять его до тех пор, пока не будут использованы все файлы, предоставленные командой find . Использование -print0 и -0 позволяет работать, если в именах файлов или каталогов есть пробелы.

В Mac OS X вы можете добиться того же эффекта без xargs:

find . -iname '*.gz' -exec zgrep PATTERN {} +
1
$ zgrep --help
Usage: /bin/zgrep [OPTION]... [-e] PATTERN [FILE]...
Look for instances of PATTERN in the input FILEs, using their
uncompressed contents if they are compressed.

Так что-то вроде

find . -iname "*.gz" -exec zgrep PATTERN {} \
1

@aioobe почти там. Команда выполнит работу, но не сообщит вам имя файла

Следующее должно также сказать вам имя файла:

find . -iname "*.gz" -exec zgrep PATTERN {} /dev/null \;

Добавление /dev/null гарантирует, что zgrep увидит два имени файла, поэтому он покажет вам имя файла, если найдет строку

РЕДАКТИРОВАТЬ

Дальнейшие исследования показывают, что для моей машины (OS/X) аргумент -exec для поиска добавляет столько имен файлов, сколько возможно (аналогично поведению xargs ).

0

Следующие работы угощение в zsh

for archive in **/*.gz; do
    echo "[${archive}] "
    gzip -dc ${archive} | grep -n "String"
done

Может также работать в bash , ksh и т.д.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .