Как совместить поиск и grep для сложного поиска? (GNU / Linux, найти, grep)

17

Я пытаюсь выполнить текстовый поиск в некоторых файлах, которые имеют похожую структуру каталогов, но не находятся в одном дереве каталогов, в GNU / Linux.

У меня есть веб-сервер со многими сайтами, которые имеют одинаковую древовидную структуру (PHP Code Framework Igniter MVC), поэтому я хочу искать в определенном каталоге по дереву для каждого сайта, например:

/srv/www/*/htdocs/system/application/

Где * это название сайта. И из этих каталогов приложений я хочу найти все дерево вплоть до его листьев, чтобы найти файл * .php, в котором есть какой-то текстовый шаблон, скажем, «debug (», регулярное выражение не требуется).

Я знаю, как использовать find и grep, но я не очень хорошо их комбинирую.

Как бы я это сделал?
Заранее спасибо!

Petruza
источник

Ответы:

21

Пытаться

find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep "debug (" {} \; -print

Это должно рекурсивно искать в папках applicationфайлы с .phpрасширением и передавать их grep.

Оптимизация для этого должна была бы выполнить:

find /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep -H "debug ("

Используется xargsдля передачи всех .phpфайлов, выводимых в findкачестве аргументов, одной grepкоманде; например, . Вариант и вариант обеспечить пробелы в именах файлов и каталогов правильно обработаны. Вариант передается гарантирует , что имя файла печатается во всех ситуациях. (По умолчанию печатает имя файла только когда передается несколько аргументов.)grep "debug (" file1 file2 file3-print0find-0xargs-Hgrepgrep

От человека xargs:

-0

      Входные элементы заканчиваются нулевым символом вместо пробела, и кавычки и обратный слеш не являются специальными (каждый символ воспринимается буквально). Отключает конец строки файла, который обрабатывается как любой другой аргумент. Полезно, когда элементы ввода могут содержать пробелы, кавычки или обратную косую черту. Опция поиска GNU -print0производит ввод, подходящий для этого режима.

Нагул
источник
1
+1. Это выполнит grep для каждого php-файла. Если есть много файлов, вы можете оптимизировать дальшеfind /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep "debug ("
Юкка Матилинен
@jackem Согласен. Я обновлю свой ответ соответственно.
Нагуль
2
Другое небольшое улучшение: xargs может просто передать одно имя файла в grep, и в этом случае grep не будет показывать имя файла, если есть совпадение. Вы можете добавить -H к команде grep, чтобы она показывала имя файла.
Рэнди Оррисон
@ Рэнди Это очень верное замечание.
Нагуль
3
Это истинная некромантия, но она GNU findможет взять на себя +оператор вместо того, \;чтобы выполнять тот же вид одиночного выполнения процесса, что xargsи. Таким образом, find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep -H "debug (" {} +делает то же самое, что и в xargsпримере в этом ответе, но с одним меньшим разветвлением процесса (и все еще 0 риска для проблем с именами файлов).
Даниэль Андерссон
10

findдаже не требуется для этого примера, можно использовать grepнапрямую (по крайней мере GNU grep):

grep -RH --include='*.php' "debug (" /srv/www/*/htdocs/system/application/

и мы дошли до единого процесса.

Параметры:

  • -R, --dereference-recursive Read all files under each directory, recursively. Follow all symbolic links, unlike -r.
  • -H, --with-filename Print the file name for each match. This is the default when there is more than one file to search.
  • --include=GLOB Search only files whose base name matches GLOB (using wildcard matching as described under --exclude).
  • --exclude=GLOB Skip any command-line file with a name suffix that matches the pattern GLOB, using wildcard matching; a name suffix is either the whole name, or any suffix starting after a / and before a +non-/. When searching recursively, skip any subfile whose base name matches GLOB; the base name is the part after the last /. A pattern can use *, ?, and [...] as wildcards, and \ to quote a wildcard or backslash character literally.
Даниэль Андерссон
источник
Просто для любопытства, что -RHозначают варианты?
Гас
@Gus: Добавлен man grepотрывок описания опций в пост.
Даниэль Андерссон
0

Ваша оболочка может найти файлы php и передать их grep. В Баш:

shopt -s nullglob globstar
grep searchterm /srv/www/*/htdocs/system/application/**/*.php
user2394284
источник