Wie kann ich den Namen der gewünschten Dateien mit Platzhaltern "grep" rekursiv filtern?

40

Wenn ich im aktuellen Verzeichnis eine rekursive grep-Suche durchführen möchte, mache ich normalerweise Folgendes:

grep -ir "string" .

Dieser Befehl durchsucht jedoch alle Arten von Dateien, einschließlich Binärdateien (Bilder, Audio, Video usw.), was zu einem sehr langsamen Suchprozess führt.

Wenn ich das zum Beispiel mache, funktioniert es nicht:

grep -ir "string" *.php

Dies funktioniert nicht, da sich im aktuellen Verzeichnis keine PHP-Dateien befinden, sich jedoch in einigen Unterverzeichnissen des aktuellen Verzeichnisses befinden und die Namen der Unterverzeichnisse nicht mit ".php" enden, sodass grep nicht in ihnen nachschaut.

Wie kann ich also eine rekursive Suche im aktuellen Verzeichnis durchführen, aber auch Platzhalter für Dateinamen angeben? (dh nur in Dateien suchen, die mit einer bestimmten Erweiterung enden)

OMA
quelle

Antworten:

58

Benutze grepdie --includeOption:

grep -ir "string" --include="*.php" .
Dan D.
quelle
1
Ok, meine Version von grep scheint alt zu sein, weil es diese Option nicht gab (kein Wunder, warum ich nicht herausfinden konnte, wie das geht!). Ich bekam die Nachricht: "grep: nicht erkannte Option" --include = *. Php "". Aber ich habe gerade ein Upgrade auf ein neues gemacht und jetzt funktioniert es. Vielen Dank!
OMA
Ich musste die Periode am Ende ersetzen und verwenden:grep -ir "string" --include="*.php" *
Stuart
Ich dachte, Periode sei nur das Ende der Reihe! Ich habe nicht gebraucht oder gebraucht.
Boardtc
14

Wenn Sie eine Version haben grep, bei der die --includeOption fehlt , können Sie Folgendes verwenden. Diese wurden beide in einer Verzeichnisstruktur wie folgt getestet:

$ tree
.
├── a
├── b
   └── foo2.php
├── c
   └── d
       └── e
           └── f
               └── g
                   └── h
                       └── foo.php
├── foo1.php
└── foo.php

Wo alle .phpDateien die Zeichenfolge enthalten string.

  1. Verwenden find

    $ find . -name '*php' -exec grep -H string {} +
    ./b/foo2.php:string
    ./foo1.php:string
    ./c/d/e/f/g/h/foo.php:string

    Erläuterung

    Dadurch werden alle .phpDateien gefunden und grep -H stringauf jeder ausgeführt. Mit findder -execOption {}wird durch jede der gefundenen Dateien ersetzt. Das -Hweist grepan, den Dateinamen sowie die übereinstimmende Zeile zu drucken.

  2. Angenommen, Sie haben eine ausreichend neue Version von bash, verwenden Sie globstar:

    $ shopt -s globstar
    $ grep -H string  **/*php
    b/foo2.php:string
    c/d/e/f/g/h/foo.php:string
    foo1.php:string

    Erläuterung

    Wie im Bash-Handbuch erklärt :

    globstar

    Wenn festgelegt, stimmt das in einem Dateinamenerweiterungskontext verwendete Muster '**' mit allen Dateien sowie mit null oder mehr Verzeichnissen und Unterverzeichnissen überein. Wenn dem Muster ein '/' folgt, stimmen nur Verzeichnisse und Unterverzeichnisse überein.

    Also, indem Sie shopt -s globstarIhnen die Funktion und Bash sind aktivierende globstarOption , die macht **/*phpalle erweitern .phpim aktuellen Verzeichnis Dateien ( **entspricht 0 oder mehr Verzeichnisse, so **/*phppaßt ./foo.phpauch) , die dann grep für string.

terdon
quelle
-2

Verwenden */*.php

Dies macht grep search zu einer Ebene des Unterverzeichnisses

Dennis Nolan
quelle
Etwas lief schief, als Sternchen und Punkte verschwanden.
Dennis Nolan
Sie können Backticks verwenden, um Code zu formatieren, und Unklarheiten hinsichtlich der Verwendung von Sternchen zur Hervorhebung bei der Formatierung von Abschriften vermeiden. PS: Beachten Sie, dass im letzten Absatz die Frage nach "rekursiver Suche" gestellt wird (aber nicht nach meiner Ablehnung).
RedGrittyBrick
Keine richtige Antwort, da es, wie Sie bereits erwähnt haben, nur für eine Ebene tiefe Verzeichnisstrukturen geeignet ist, aber trotzdem gut zu wissen ist;). Mein Lob dafür.
OMA