Як поєднати пошук і греп для складного пошуку? (GNU / linux, find, grep)


17

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

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

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

Де * - назва сайту. І з цих каталогів додатків я хочу шукати все дерево до його листя, щоб мати * .php файл, який має деякий шаблон тексту всередині, скажімо, "налагодження (", регулярне вираження не потрібно).

Я знаю, як використовувати find і grep, але я не вмію їх поєднувати.

Як би я це зробив?
Спасибі заздалегідь!

Відповіді:


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

Від man xargs:

-0

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


1
+1. Однак це виконає grep для кожного файлу php. Якщо файлів багато, ви можете оптимізувати даліfind /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep "debug ("
Jukka Matilainen,

@jackem Погодився. Відповідно оновлю відповідь.
nagul

2
Ще одне невелике вдосконалення: xargs може просто передати одне ім’я файлу grep, і в цьому випадку grep не відображатиме ім'я файлу, якщо є збіг. Ви можете додати -H до команди grep, щоб змусити її показувати ім'я файлу.
Ренді Оріссон

@Randy Це дуже вагомий момент.
nagul

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. В bash:

shopt -s nullglob globstar
grep searchterm /srv/www/*/htdocs/system/application/**/*.php
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.