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

21163
Petruza

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

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

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

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

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

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

15

3 ответа на вопрос

18
nagul

Try

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

This should recursively search the folders under application for files with .php extension and pass them to grep.

An optimization on this would be to execute:

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

This uses xargs to pass all the .php files output by find as arguments to a single grep command; e.g., grep "debug (" file1 file2 file3. The -print0 option of find and -0 option of xargs ensure the spaces in file and directory names are correctly handled. The -H option passed to grep ensures that the filename is printed in all situations. (By default, grep prints the filename only when multiple arguments are passed in.)

From man xargs:

-0

      Input items are terminated by a null character instead of by whitespace, and the quotes and backslash are not special (every character is taken literally).  Disables the end of file string, which is treated like any other argument.  Useful when input items might contain white space, quote marks, or backslashes.  The GNU find -print0 option produces input suitable for this mode.

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

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 7 лет назад 0
@Gus: Добавлена ​​выдержка из описания опций `man grep`. Daniel Andersson 6 лет назад 0
0
user2394284

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

shopt -s nullglob globstar grep searchterm /srv/www/*/htdocs/system/application/**/*.php 

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