Unix 'grep' для рядка у всіх gzip-файлах у всіх підкаталогах


Відповіді:


13

@Steve Weet майже є. Використання / dev / null в якості додаткового аргументу є хорошим способом змусити показ імені файлу (я пам’ятаю, що, дякую Стіву), але він все ще запускає exec для кожного знайденого файлу - величезна накладні витрати.

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

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

xargsнадасть якомога більше аргументів (іменних файлів) для згрепу та повторно виконуватиме його, поки він не використає всі файли, надані findкомандою. Використання -print0і -0параметрів дозволяє йому працювати, якщо в будь-якому з назв файлів чи каталогів є пробіли.

На Mac OS X ви можете досягти такого ж ефекту без xargs:

find . -iname '*.gz' -exec zgrep PATTERN {} +

+1 Це справді приємно. Я не розумів, що xargs передає більше ніж один аргумент. Значній частині мого * nix командного рядка-фу вже 20 років, і я не думаю, що xargs зробив це 20 років тому.
Стів Вет

Виявляється, знахідка на os / x поводиться так само, як і xargs
Стів Вет

1
Дивіться мій коментар до відповіді Стіва Вета щодо "+", що закінчується на -exec.
Даніель Андерссон

Використовуйте, -Hщоб завжди показувати ім'я файлу відповідним рядком, принаймні в GNU grep.
Даніель Андерссон

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 {} \

-Exec створить новий екземпляр zgrep для кожного файлу, який він повторює, щоб запобігти перегляду імені файлу. Було б краще скористатися zgrep -rдля переходу через дерево, або якщо -r не працює, xargs zgrep
передайте

Я потрапляю /bin/zgrep: -r: option not supportedна свою недавно встановлену систему ubuntu.
aioobe

Ви можете використовувати xargsзамість цього тоді.
Нуфал Ібрагім

Дивіться мій коментар до відповіді Стіва Вета щодо "+", що закінчується на -exec.
Даніель Андерссон

1

@aioobe майже є. Команда виконає цю роботу, але не повідомить вам ім'я файлу

Нижче слід вказати і ім’я файлу:

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

Додавання /dev/nullбуде гарантувати, що zgrep бачить дві імена файлів, тому він покаже вам ім'я файлу, якщо він знайде рядок

EDIT

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


Це дуже круто, я не знав цього про OSX -exec- я все про портативність, тому я б не використовував його в сценарії, але відмінно підходить для командного рядка.

Для інших версій знаходження, використовуючи "+" замість "\;" щоб закінчити оператор exec буде робити те саме, що OSX, розповідями в цій темі, робить за замовчуванням. Дивіться ручний запис для команди "-exec {} +". Це стосується не всіх версій find, але більшості сучасних (наприклад, у дистрибутивах на основі Debian).
Даніель Андерссон

Використовуйте, -Hщоб завжди показувати ім'я файлу з відповідним рядком, принаймні, у GNU grep замість /dev/nullхака.
Даніель Андерссон

0

Далі працює обробка в zsh

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

Він також може працювати в bash, kshі т.д. ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.