Wie suche ich mit `grep` nach einer Zeichenfolge in einer PHP-Datei?
11
Ich suche nach einer Klassendeklaration auf einer Site mit Hunderten von PHP-Dateien. Wie kann ich dies im aktuellen Ordner und in den Unterordnern mit grep tun ?
Wenn dies zu Superuser migriert wird, möchten Sie möglicherweise etwas über das sagen, was Sie wollten, was Ihnen grep -rnicht gegeben hat.
Ich bin verwirrt - hast du dir nicht einfach selbst geantwortet? Was waren die Ergebnisse dieser Linie? Versuchen Sie es weiter zu optimieren? Bitte stellen Sie sich vor, diese Frage als jemand anderes zu lesen, da sie verwirrend und unklar ist.
Meder Omuraliev
@ andere Kommentare: Seine grep -r Aussage gibt nicht, was er will, es sei denn, alle Ordner enden mit .php, was wahrscheinlich nicht der Fall ist ...
David Oneill
Ich habe überhaupt nichts bekommen. Ich nehme an, es hat nicht funktioniert, weil ich weiß, dass es es findet, wenn ich in dem Ordner bin, in dem sich die Datei mit dieser Klasse befindet
Ich habe die Datei durch Glück gefunden. Bei der Suche nach der Datei in dem Ordner, in dem sich die PHP-Datei mit dieser Zeile befindet, wird sie gefunden (keine Notwendigkeit für -r). Wenn ich eine CD in das Stammverzeichnis lege und die Suche mit Rekursion -r durchführe, wird nichts zurückgegeben.
Dies setzt natürlich voraus, dass Sie nur einen einzigen Abstand zwischen classund myClassmöglicherweise nicht wahr haben. Es ist jedoch einfach, den regulären Ausdruck zu ändern, um nach einer beliebigen Anzahl von Leerzeichen zu suchen.
Wenn Sie verwenden -r, möchten Sie wahrscheinlich nur das aktuelle Verzeichnis rekursiv durchsuchen :
grep -r 'class MyClass' .
Beachten Sie den Punkt am Ende des oben genannten.
Was Sie gesagt haben, grepwar, dass Sie wollten, dass jede *.phpDatei oder jedes Verzeichnis rekursiv durchsucht wird , aber Sie hatten wahrscheinlich keine Verzeichnisse, die mit der Erweiterung .php endeten. Das Obige ist die einfachste Möglichkeit, die Suche durchzuführen, enthält jedoch auch Dateien anderer Typen, was besonders problematisch ist, wenn Sie überall .svn-Verzeichnisse haben. Wenn Sie nicht viele andere Dateitypen haben, ist das oben Genannte im Allgemeinen ausreichend und funktioniert gut.
Die meisten Inkarnationen von grep haben keine Möglichkeit, Dateierweiterungen anzugeben, die durchsucht werden können. Daher verwenden Sie find im Allgemeinen in Verbindung damit:
-inameteilt einigen Versionen von grep mit, dass Sie eine Dateinamensuche ohne Berücksichtigung der Groß- und Kleinschreibung durchführen möchten, aber viele der Nicht-GNU-Varianten von find unterstützen dies nicht, sodass Sie sie -namestattdessen verwenden können.
Die -execobige Option hat den Nebeneffekt, dass für jede Datei grep aufgerufen wird, was ziemlich kostspielig ist.
Wieder andere Versionen von grep unterstützen a, mit +dem find angewiesen wird, die Argumente zusammenzufügen, um die Anzahl der Aufrufe der ausführbaren Datei zu verringern:
xargsist klug genug, um grep bis zur maximalen Anzahl von Argumenten zu übergeben, die in der Befehlszeile unterstützt werden, aber die obige Variante behandelt bestimmte Zeichen wie Leerzeichen nicht sehr gut. Wäre beispielsweise 'the file.php', würde ein Dateiname grep 'the' als Argument und 'file.php' als Argument erhalten, sodass beide nicht gefunden würden. Stattdessen verwenden wir:
print0und -0arbeiten Sie zusammen und verwenden Sie Argumente, denen ein Nullzeichen folgt, damit das Argument vollständig und eindeutig identifiziert wird.
Wenn Sie jemals mehr als ein Leerzeichen classoder eine Registerkarte haben, möchten Sie möglicherweise mehr Zeichen zulassen, indem Sie den regulären Ausdruck ändern:class[ \t]*MyClass
Dieser Beitrag zu StackOverflow enthält weitere Beispiele und zeigt, wie bestimmte Verzeichnisse wie .svn-Verzeichnisse ausgeschlossen werden.
Möglicherweise möchten Sie die Groß- und Kleinschreibung nicht berücksichtigen und Leerzeichen tolerieren. Grep wird beendet, wenn im aktuellen Verzeichnis keine Instanzen des gewünschten Dateimusters gefunden werden. Es muss sozusagen wissen, wo es anfangen soll, und keine übereinstimmenden Dateien erzeugen keinen Startpfad.
Wenn mindestens eine Datei mit der gewünschten Erweiterung vorhanden ist, können Sie egrep -ir verwenden. findund xargszeigen Sie ihre Leistungsfähigkeit mit einzelnen flachen (aber sehr großen) Verzeichnissen, in denen grep fehlschlägt, und zusätzlichen Qualifikationsmerkmalen (zum Beispiel, wenn Sie nur nach .inc-, .php- und php3-Dateien suchen möchten). Aber meiner Erfahrung nach verliert es einiges an Bequemlichkeit und Geschwindigkeit. Für von Menschen geschriebene Klassenerklärungen wird ein großes Problem das Leerzeichen sein. Verwenden Sie also egrep anstelle von grep. Auch LC_ALL = C für zusätzliche Geschwindigkeit. Der Einfachheit halber benutze ich oft:
-i -- case insensitive
-r -- recursive for all file pattern (here *)
-n -- include the line number
LC_ALL=C -- search in ASCII, not in utf8, this is much faster.
[ ]* -- match any number of spaces before the class name
([ ]|\n) -- match a space or newline after the classname
Dies kann immer noch mit Kommentaren übereinstimmen, wie z. B. // class myclass exists in file, aber ich finde, dass diese relativ klein sind und mit denen herausgefiltert werden können... | fgrep -v '//'
Sie können auch komplexere Dateimasken (z. B. um die meisten .inc- und .php-Dateien abzufangen) in das egrep-Dateimuster einfügen:
egrep "pattern" *.[ip]*
Das (mit den ersten Optionen) wird ziemlich schnell sein und meistens auf PHP-Dateien beschränkt sein.
Ich weiß, es heißt verwenden grep, aber mein persönlicher Favorit ist zu verwenden ack-grep:
ack-grep "class MyClass"
Dies wird rekursiv ausgeführt, listet den Dateinamen auf, in dem die Ergebnisse gefunden werden, mit den Zeilennummern, in denen sie gefunden werden, und hebt sie hervor. Um PHP-Dateien gezielt auszurichten, können Sie Folgendes ausführen:
ack-grep --type-set php:ext:php "path"
Das Paket bietet eine Vielzahl von Optionen. Ich würde es auf jeden Fall empfehlen (und die dazugehörige Manpage durchsuchen), um ausgefallene Dinge zu tun.
grep -r
nicht gegeben hat.Antworten:
Du kannst es versuchen
quelle
Ich würde empfehlen, dass Sie so etwas wie ctags verwenden, anstatt es mit einem grep zu tun. Wenn Sie möchten, können Sie jedoch so etwas tun
Dies setzt natürlich voraus, dass Sie nur einen einzigen Abstand zwischen
class
undmyClass
möglicherweise nicht wahr haben. Es ist jedoch einfach, den regulären Ausdruck zu ändern, um nach einer beliebigen Anzahl von Leerzeichen zu suchen.quelle
Wenn Sie verwenden
-r
, möchten Sie wahrscheinlich nur das aktuelle Verzeichnis rekursiv durchsuchen :Beachten Sie den Punkt am Ende des oben genannten.
Was Sie gesagt haben,
grep
war, dass Sie wollten, dass jede*.php
Datei oder jedes Verzeichnis rekursiv durchsucht wird , aber Sie hatten wahrscheinlich keine Verzeichnisse, die mit der Erweiterung .php endeten. Das Obige ist die einfachste Möglichkeit, die Suche durchzuführen, enthält jedoch auch Dateien anderer Typen, was besonders problematisch ist, wenn Sie überall .svn-Verzeichnisse haben. Wenn Sie nicht viele andere Dateitypen haben, ist das oben Genannte im Allgemeinen ausreichend und funktioniert gut.Die meisten Inkarnationen von grep haben keine Möglichkeit, Dateierweiterungen anzugeben, die durchsucht werden können. Daher verwenden Sie find im Allgemeinen in Verbindung damit:
-iname
teilt einigen Versionen von grep mit, dass Sie eine Dateinamensuche ohne Berücksichtigung der Groß- und Kleinschreibung durchführen möchten, aber viele der Nicht-GNU-Varianten von find unterstützen dies nicht, sodass Sie sie-name
stattdessen verwenden können.Die
-exec
obige Option hat den Nebeneffekt, dass für jede Datei grep aufgerufen wird, was ziemlich kostspielig ist.Wieder andere Versionen von grep unterstützen a, mit
+
dem find angewiesen wird, die Argumente zusammenzufügen, um die Anzahl der Aufrufe der ausführbaren Datei zu verringern:Ein häufig empfohlener Weg, um Aufrufe zu reduzieren, ist die Verwendung von xargs, die grep so oft wie möglich, aber so oft wie nötig auslösen:
xargs
ist klug genug, um grep bis zur maximalen Anzahl von Argumenten zu übergeben, die in der Befehlszeile unterstützt werden, aber die obige Variante behandelt bestimmte Zeichen wie Leerzeichen nicht sehr gut. Wäre beispielsweise 'the file.php', würde ein Dateiname grep 'the' als Argument und 'file.php' als Argument erhalten, sodass beide nicht gefunden würden. Stattdessen verwenden wir:print0
und-0
arbeiten Sie zusammen und verwenden Sie Argumente, denen ein Nullzeichen folgt, damit das Argument vollständig und eindeutig identifiziert wird.Wenn Sie jemals mehr als ein Leerzeichen
class
oder eine Registerkarte haben, möchten Sie möglicherweise mehr Zeichen zulassen, indem Sie den regulären Ausdruck ändern:class[ \t]*MyClass
Dieser Beitrag zu StackOverflow enthält weitere Beispiele und zeigt, wie bestimmte Verzeichnisse wie .svn-Verzeichnisse ausgeschlossen werden.
quelle
Mit dem immer wunderbaren ack ,
quelle
durchsucht alle Ordner mit Namen, die mit .php enden
sucht in allen Dateien in allen Unterordnern nach der Klasse MyClass und gibt dann nur diejenigen zurück, die .php enthalten.
quelle
find . -type f -name *.php -print -exec grep \"class MyClass\" {} \;
Sie erhalten den Inhalt der Zeile sowie den Pfad zur Datei.quelle
Falls die übereinstimmenden Dateien möglicherweise beliebige Namen haben, sollten Sie die Verwendung in Betracht ziehen
-print0
quelle
l zeigt nur den Dateinamen
r ist rekursiv
. sucht im aktuellen Ordner
--include begrenzt die Dateinamenerweiterung
quelle
Möglicherweise möchten Sie die Groß- und Kleinschreibung nicht berücksichtigen und Leerzeichen tolerieren. Grep wird beendet, wenn im aktuellen Verzeichnis keine Instanzen des gewünschten Dateimusters gefunden werden. Es muss sozusagen wissen, wo es anfangen soll, und keine übereinstimmenden Dateien erzeugen keinen Startpfad.
Wenn mindestens eine Datei mit der gewünschten Erweiterung vorhanden ist, können Sie egrep -ir verwenden.
find
undxargs
zeigen Sie ihre Leistungsfähigkeit mit einzelnen flachen (aber sehr großen) Verzeichnissen, in denen grep fehlschlägt, und zusätzlichen Qualifikationsmerkmalen (zum Beispiel, wenn Sie nur nach .inc-, .php- und php3-Dateien suchen möchten). Aber meiner Erfahrung nach verliert es einiges an Bequemlichkeit und Geschwindigkeit. Für von Menschen geschriebene Klassenerklärungen wird ein großes Problem das Leerzeichen sein. Verwenden Sie also egrep anstelle von grep. Auch LC_ALL = C für zusätzliche Geschwindigkeit. Der Einfachheit halber benutze ich oft:LC_ALL=C egrep -irn "class[ ]*myclass([ ]|\n)" * | egrep "\.(inc|php[35]?)"
Dies kann immer noch mit Kommentaren übereinstimmen, wie z. B.
// class myclass exists in file
, aber ich finde, dass diese relativ klein sind und mit denen herausgefiltert werden können... | fgrep -v '//'
Sie können auch komplexere Dateimasken (z. B. um die meisten .inc- und .php-Dateien abzufangen) in das egrep-Dateimuster einfügen:
egrep "pattern" *.[ip]*
Das (mit den ersten Optionen) wird ziemlich schnell sein und meistens auf PHP-Dateien beschränkt sein.
HTH
quelle
Ich weiß, es heißt verwenden
grep
, aber mein persönlicher Favorit ist zu verwendenack-grep
:Dies wird rekursiv ausgeführt, listet den Dateinamen auf, in dem die Ergebnisse gefunden werden, mit den Zeilennummern, in denen sie gefunden werden, und hebt sie hervor. Um PHP-Dateien gezielt auszurichten, können Sie Folgendes ausführen:
Das Paket bietet eine Vielzahl von Optionen. Ich würde es auf jeden Fall empfehlen (und die dazugehörige Manpage durchsuchen), um ausgefallene Dinge zu tun.
quelle