Ответы:
Что ж, общий случай, который работает с любой командой, которая пишет в stdout, - это использование xargs
, которое позволит вам присоединить любое количество аргументов командной строки к концу команды:
$ find … | xargs grep 'search'
Или встроить команду в вашу grep
строку с помощью обратных кавычек или $()
, которая запустит команду и подставит ее вывод:
$ grep 'search' $(find …)
Обратите внимание, что эти команды не работают, если имена файлов содержат пробелы или некоторые другие «странные символы» ( \'"
для xargs, \[*?
для $(find …)
).
Однако в конкретном случае find
возможность выполнения программы по заданным аргументам является встроенной:
$ find … -exec grep 'search' {} \;
Все, что находится между -exec
и ;
является командой для выполнения; {}
заменяется найденным именем файла find
. Это будет выполняться отдельно grep
для каждого файла; поскольку grep
может занять много имен файлов и искать их все, вы можете изменить , ;
чтобы +
сказать найти , чтобы передать все совпадающие имена файлов grep
сразу:
$ find … -exec grep 'search' {} \+
find ... -type f -print0 | xargs -r0 grep 'search' /dev/null
. QED. Хотя -exec +
это очень эффективно, его нет на всех версиях find.
$ find … -exec grep 'search' {} \+
форма намного быстрее.
В некоторых версиях grep
(например, в не встроенных Linux, BSD или Mac OS X) есть -r
возможность сделать рекурсивный поиск. В OpenBSD используйте -R
(и нет, --exclude
как в примере ниже). Это охватывает простые комбинации find
с grep
.
Если ваша реализация не имеет -R
флага, или если вам нужны более подходящие критерии соответствия файлов, вы можете использовать -exec
основной из них, find
чтобы заставить его выполняться grep
. Несколько более старых find
реализаций не поддерживают -exec
... +
; в этих системах используйте ;
вместо +
(это будет вызываться grep
один раз для каждого файла, так что это будет медленнее, но в противном случае результат будет таким же). Обратите внимание на /dev/null
хитрость, позволяющую grep
отображать имя файла, даже если оно вызывается в одном файле (GNU grep и FreeBSD / NetBSD / OSX grep имеют -H
опцию для достижения того же эффекта).
find . -type f -name '*.o' -prune -o -exec grep 'needle' /dev/null {} +
grep -r --exclude='*.o' 'needle' .
GNU grep
имеет -H
возможность всегда печатать имя файла.