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

53755
OMA

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 Suchvorgang führt.

Wenn ich das zum Beispiel mache, funktioniert es nicht:

grep -ir "string" *.php 

Es funktioniert nicht, weil sich im aktuellen Verzeichnis keine PHP-Dateien befinden, aber in einigen der Unterverzeichnisse im aktuellen Verzeichnis, und die Namen der Unterverzeichnisse enden nicht mit ".php", sodass grep nicht in sie hineinschaut.

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

33

3 Antworten auf die Frage

46
Dan D.

Verwenden Sie grepdie --includeOption:

grep -ir "string" --include="*.php" . 
Ok, es scheint, dass meine Version von grep alt war, weil sie diese Option nicht hatte (kein Wunder, warum ich nicht herausfinden konnte, wie ich das mache!). Ich habe die Meldung erhalten: "grep: nicht erkannte Option --include = *. Php '". Aber ich habe gerade auf ein neueres upgegradet und jetzt funktioniert es. Vielen Dank! OMA vor 10 Jahren 1
Ich musste den Punkt am Ende ersetzen und verwenden: `grep -ir" string "--include =" *. Php "*` Stuart vor 9 Jahren 0
Ich dachte, die Periode wäre nur das Ende der Zeile! Ich habe nicht gebraucht oder brauche. boardtc vor 6 Jahren 0
14
terdon

Wenn Sie über eine Version verfügen grep, bei der die --includeOption fehlt, können Sie Folgendes verwenden. Beide wurden 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. Benutzen 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 anschließend grep -H stringauf jeder von ihnen ausgeführt. Mit findder -execOption {}wird durch jede der gefundenen Dateien ersetzt. Der -HBefehl grepzum Ausdrucken des Dateinamens sowie der übereinstimmenden Zeile.

  2. Angenommen, Sie haben eine neue Version von genug 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 gesetzt, stimmt das in einem Dateinamenerweiterungskontext verwendete Muster '**' mit allen Dateien und mit null oder mehr Verzeichnissen und Unterverzeichnissen überein. Wenn auf das 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.

-2
Dennis Nolan

Use */*.php

This makes grep search one level of subdirectory

Etwas ging schief, als Sternchen und Punkte verschwanden. Dennis Nolan vor 8 Jahren 0
Sie können Backticks verwenden, um Code zu formatieren und Mehrdeutigkeiten bei der Verwendung von Sternchen zur Hervorhebung der Markdown-Formatierung zu vermeiden. PS stellt fest, dass die Frage im letzten Absatz nach "rekursiver Suche" gefragt wird (nicht jedoch mein Downvote). RedGrittyBrick vor 8 Jahren 0
Keine richtige Antwort, da dies, wie Sie erwähnen, nur für Verzeichnisstrukturen mit einer Ebene geeignet ist, aber trotzdem gut zu wissen ist;). Meine Zusage dafür. OMA vor 7 Jahren 0