Jak połączyć wyszukiwanie i grep w celu kompleksowego wyszukiwania? (GNU / linux, znajdź, grep)

17

Próbuję przeprowadzić wyszukiwanie tekstowe w niektórych plikach o podobnej strukturze katalogów, ale nie w tym samym drzewie katalogów w systemie GNU / Linux.

Mam serwer WWW z wieloma witrynami, które mają tę samą strukturę drzewa (framework PHP Igniter MVC PHP), dlatego chcę wyszukać w określonym katalogu w dół drzewa dla każdej witryny, na przykład:

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

Gdzie * to nazwa strony. I z tych katalogów aplikacji chcę przeszukać całe drzewo, aż do jego liści, w poszukiwaniu pliku * .php, który ma wewnątrz pewien wzorzec tekstowy, powiedzmy „debuguj” (nie wymaga wyrażenia regularnego).

Wiem, jak używać find i grep, ale nie jestem dobry w ich łączeniu.

Jak mam to zrobić?
Z góry dziękuję!

Petruza
źródło

Odpowiedzi:

21

Próbować

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

Powinno to rekurencyjnie przeszukiwać foldery w applicationposzukiwaniu plików z .phprozszerzeniem i przekazywać je do grep.

Optymalizacją tego byłoby wykonanie:

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

Służy xargsdo przekazywania wszystkich .phpplików wyjściowych findjako argumentów do pojedynczego greppolecenia; np . Opcja i możliwość zapewnienia spacje w nazwach plików i katalogów są prawidłowo obsługiwane. Opcja przekazane zapewnia, że nazwa pliku jest drukowany w każdej sytuacji. (Domyślnie drukuje nazwę pliku tylko wtedy, gdy przekazanych jest wiele argumentów.)grep "debug (" file1 file2 file3-print0find-0xargs-Hgrepgrep

Od man xargs:

-0

      Elementy wejściowe są zakończone znakiem null zamiast spacją, a cudzysłowy i ukośniki odwrotne nie są wyjątkowe (każdy znak jest traktowany dosłownie). Wyłącza koniec ciągu pliku, który jest traktowany jak każdy inny argument. Przydatne, gdy elementy wejściowe mogą zawierać spacje, znaki cudzysłowu lub ukośniki odwrotne. Opcja wyszukiwania GNU -print0tworzy dane wejściowe odpowiednie dla tego trybu.

nagul
źródło
1
+1. To jednak wykona grep dla każdego pliku php. Jeśli jest dużo plików, możesz dalej optymalizować przezfind /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep "debug ("
Jukka Matilainen
@jackem Zgoda. Zaktualizuję odpowiednio swoją odpowiedź.
nagul
2
Kolejne małe ulepszenie: xargs może po prostu przekazać jedną nazwę pliku do grep, w którym to przypadku grep nie wyświetli nazwy pliku, jeśli jest zgodny. Możesz dodać -H do polecenia grep, aby zmusić go do wyświetlenia nazwy pliku.
Randy Orrison
@Randy To bardzo ważny punkt.
nagul
3
Jest to prawdziwa nekromancja, ale GNU findmoże wymagać od +operatora zamiast \;wykonania tego samego rodzaju wykonywania pojedynczego procesu, co xargsrobi. W ten sposób find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep -H "debug (" {} +robi to samo, co w xargsprzykładzie w tej odpowiedzi, ale z jednym rozwidleniem procesu (i nadal 0 ryzykiem problemów z nazwą pliku).
Daniel Andersson
10

findnie jest nawet potrzebny w tym przykładzie, można użyć grepbezpośrednio (przynajmniej GNU grep):

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

i jesteśmy do jednego rozwidlenia procesu.

Opcje:

  • -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.
Daniel Andersson
źródło
Dla ciekawości, co -RHoznaczają te opcje?
Gus,
@Gus: Dodano man grepfragment opisu opcji do postu.
Daniel Andersson
0

Twoja powłoka może znaleźć pliki php i przekazać je grep. W bash:

shopt -s nullglob globstar
grep searchterm /srv/www/*/htdocs/system/application/**/*.php
użytkownik2394284
źródło