Wie kombiniere ich find und grep für eine komplexe Suche? (GNU / Linux, find, grep)

17

Ich versuche, eine Textsuche in einigen Dateien durchzuführen, die eine ähnliche Verzeichnisstruktur haben, sich jedoch nicht in derselben Verzeichnisstruktur in GNU / Linux befinden.

Ich habe einen Webserver mit vielen Sites, die dieselbe Baumstruktur haben (Code Igniter MVC PHP Framework). Daher möchte ich für jede Site in einem bestimmten Verzeichnis im Baum suchen. Beispiel:

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

Wobei * der Site-Name ist. Und in diesen Anwendungsverzeichnissen möchte ich den gesamten Baum bis auf die Blätter durchsuchen und nach einer * .php-Datei suchen, die ein Textmuster enthält. Sagen wir "debug (", kein regulärer Ausdruck erforderlich.

Ich weiß, wie man find und grep benutzt, aber ich kann sie nicht gut kombinieren.

Wie würde ich das machen?
Danke im Voraus!

Petruza
quelle

Antworten:

20

Versuchen

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

Dadurch sollten die Ordner unter rekursiv nach applicationDateien mit der .phpErweiterung durchsucht und an übergeben werden grep.

Eine Optimierung hierzu wäre:

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

Hiermit werden xargsalle .phpausgegebenen Dateien findals Argumente an einen einzelnen grepBefehl übergeben. zB . Die Option und die Option zum Sicherstellen, dass die Leerzeichen in Datei- und Verzeichnisnamen korrekt behandelt werden. Die an übergebene Option stellt sicher, dass der Dateiname in allen Situationen gedruckt wird. (Standardmäßig wird der Dateiname nur gedruckt, wenn mehrere Argumente übergeben werden.)grep "debug (" file1 file2 file3-print0find-0xargs-Hgrepgrep

Von Mann Xargs:

-0

      Eingabeelemente werden durch ein Nullzeichen anstelle von Leerzeichen abgeschlossen, und die Anführungszeichen und der Backslash sind keine besonderen Zeichen (jedes Zeichen wird wörtlich genommen). Deaktiviert das Ende der Dateizeichenfolge, die wie jedes andere Argument behandelt wird. Nützlich, wenn Eingabeelemente Leerzeichen, Anführungszeichen oder umgekehrte Schrägstriche enthalten können. Die GNU- -print0Suchoption erzeugt Eingaben, die für diesen Modus geeignet sind.

Nagul
quelle
1
+1. Dadurch wird grep jedoch für jede PHP-Datei ausgeführt. Wenn es viele Dateien gibt, können Sie weiter optimieren, indem Siefind /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep "debug ("
Jukka Matilainen
@ Jackem Einverstanden. Ich werde meine Antwort entsprechend aktualisieren.
Nagul
2
Eine weitere kleine Verbesserung: xargs kann nur einen Dateinamen an grep übergeben. In diesem Fall zeigt grep den Dateinamen nicht an, wenn eine Übereinstimmung vorliegt. Sie können -H zum Befehl grep hinzufügen, um die Anzeige des Dateinamens zu erzwingen.
Randy Orrison
@ Randy Das ist ein sehr gültiger Punkt.
Nagul
3
Dies ist eine echte Nekromantie, GNU findkann jedoch den +Operator \;erfordern, anstatt die gleiche Art der Einzelprozessausführung auszuführen, wie dies der Fall ist xargs. So find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep -H "debug (" {} +macht das gleiche wie das xargsBeispiel in dieser Antwort, aber mit einer weniger Prozess Gabel (und immer noch 0 Risiko für Namen Probleme Datei).
Daniel Andersson
10

findwird für dieses Beispiel nicht einmal benötigt, man kann grepdirekt (zumindest GNU grep) verwenden:

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

und wir sind auf eine einzelne Prozessgabel zurückzuführen.

Optionen:

  • -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
quelle
Was bedeuten die -RHOptionen nur aus Neugier ?
Gus
@Gus: man grepAuszug der Optionsbeschreibungen zum Beitrag hinzugefügt .
Daniel Andersson
0

Ihre Shell kann die PHP-Dateien finden und an grep übergeben. In der Bash:

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