Як мені передати список файлів для отримання grep


98

Я використовую findі отримую список файлів, grepчерез які хочу перейти . Як мені подати цей список grep?

Відповіді:


116

Ну, загальний випадок, який працює з будь-якою командою, що пише в 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' {} \+

1
Слід зазначити, що перші дві форми не працюють з назви файлів, що містять пробіли.
enzotib

1
Я віддаю перевагу find ... -type f -print0 | xargs -r0 grep 'search' /dev/null. QED. Хоча -exec +це дуже ефективно, він існує не у всіх версіях пошуку.
Арседж

На жаль, я не можу перевірити вас правильність 3 рази.
Аркабард

3
Я пропоную використовувати -exec, а не the xargs. Якщо ви використовуєте -execв системі find, вона буде створювати тільки один оболонку Grep для контенту. Якщо ви користуєтесь xargs, це створить дві оболонки: одну для, findа другу для xargs.

2
Експериментом я виявляю, що $ find … -exec grep 'search' {} \+форма набагато швидша.
gogoud

9

У деяких версіях 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' .

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