Відповіді:
Ну, загальний випадок, який працює з будь-якою командою, що пише в stdout, полягає у використанні xargs
, яке дозволить вам приєднати будь-яку кількість аргументів командного рядка до кінця команди:
$ find … | xargs grep 'search'
Або вбудувати команду у свій grep
рядок із зворотними посиланнями або $()
, яка запустить команду та замінить її вихід:
$ grep 'search' $(find …)
Зауважте, що ці команди не працюють, якщо імена файлів містять пробіл або певні інші "дивні символи" ( \'"
для xargs, \[*?
for $(find …)
).
Однак у конкретному випадку find
можливість виконання програми на заданих аргументах вбудована:
$ find … -exec grep 'search' {} \;
Все між -exec
і ;
є командою для виконання; {}
замінюється на ім'я файлу, знайдене find
. Це виконає окремий grep
для кожного файлу; оскільки grep
можна приймати багато імен і шукати їх усі, ви можете змінити на ;
to +
to find find, щоб передати всі відповідні імена файлів grep
одразу:
$ find … -exec grep 'search' {} \+
find ... -type f -print0 | xargs -r0 grep 'search' /dev/null
. QED. Хоча -exec +
це дуже ефективно, він існує не у всіх версіях пошуку.
$ 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
можливість завжди друкувати ім'я файлу.