Как я передаю список файлов к grep

Ваш пример только распечатывает количество случаев на строку а не общее количество в файле. Если это - то, что Вы хотите, что-то вроде этого могло бы работать:

perl -nle '$c+=scalar(()=m/needle/g);END{print $c}' 
100
07.09.2011, 21:39
3 ответа

Ну, универсальный случай, который работает с любой командой, которая пишет в 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' {} \+
121
27.01.2020, 19:30
  • 1
    Должен быть отмечен, что сначала две формы не делают работ с именами файлов, содержащими пробелы. –  enzotib 07.09.2011, 22:09
  • 2
    я предпочитаю find ... -type f -print0 | xargs -r0 grep 'search' /dev/null. ЧТО И ТРЕБОВАЛОСЬ ДОКАЗАТЬ. В то время как -exec + очень эффективно, это не существует на всей версии находки. –  Arcege 07.09.2011, 22:11
  • 3
    Печально я не могу проверить, что Вы исправляете 3 раза. –  MageProspero 07.09.2011, 22:43
  • 4
    я предлагаю использовать -exec, вместо, чем xargs. Если Вы используете -exec в find, это создаст только одну оболочку к grep для содержания. Если Вы используете xargs, это создаст две оболочки: один для find и другой для xargs. –   18.01.2012, 20:32
  • 5
    экспериментом я нахожу что $ find … -exec grep 'search' {} \+ форма является очень самой быстрой. –  gogoud 14.11.2016, 12:32

Некоторые версии grep (например, на невстроенном Linux или BSD или  Mac OS X), имеют a -r опция сделать рекурсивный поиск. На OpenBSD использовать -R (и существует нет --exclude как в примере ниже). Это покрывает простые комбинации find с grep.

Если Ваша реализация не имеет -R флаг, или если Вы хотите более необычные критерии соответствия файла, можно использовать -exec основной из find заставить его выполниться grep. Некоторые более старые find реализации не поддерживают -exec+; в этих системах используйте a ; вместо + (это будет звонить grep однажды на файл, таким образом, это будет медленнее, но иначе результатом будет то же). Отметьте /dev/null обманите для порождения grep показать имя файла, даже если это, оказывается, называют на единственном файле (GNU grep и FreeBSD/NetBSD/OSX grep имеют a -H опция достигнуть того же эффекта).

find . -type f -name '*.o' -prune -o -exec grep 'needle' /dev/null {} +
grep -r --exclude='*.o' 'needle' .
9
27.01.2020, 19:30
  • 1
    GNU grep имеет -H опция всегда распечатать имя файла. –  enzotib 08.09.2011, 15:11
find... | while read line; do grep <regex> "$line"; done
1
18.09.2020, 12:27

Теги

Похожие вопросы