Wie durchläuft man alle Dateien im aktuellen Verzeichnis und in den Unterverzeichnissen, um eine Zeichenfolge zu finden?

Wie durchläuft man alle Dateien im aktuellen Verzeichnis und in den Unterverzeichnissen, um eine Zeichenfolge zu finden?

Hallo, ich versuche, ein Verzeichnis und alle seine Unterverzeichnisse zu durchlaufen, um beispielsweise in allen Dateien die Zeichenfolge „foo“ zu finden. Anschließend möchte ich die Dateinamen (einschließlich des vollständigen Pfads) aller Dateien anzeigen, die diese Zeichenfolge enthalten.

Das Betriebssystem ist Unix und verwendet die Bash-Shell.

Ich bin für jeden Vorschlag dankbar. Danke

Antwort1

Sie können eine rekursive Funktion verwenden . Zumindest grepin GNU ist dies die Option:grep-R

grep -R foo /path/to/parent/directory

Wenn Sie beispielsweise einen vollständigen Pfad verwenden, wie oben, /home/callsign223/foo/werden alle Dateien mit ihren qualifizierten Pfaden angezeigt. Und wenn Sie nur die Dateinamen sehen möchten, nicht die entsprechenden Zeilen, können Sie -lnur den Dateinamen ausgeben:

grep -lR foo /path/to/parent/directory

Beachten Sie, dass die -ROption nicht portierbar ist und nicht von allen grepImplementierungen unterstützt wird.

Antwort2

Wenn grep -Rdies keine Option ist, können Sie für jede Datei findFolgendes ausführen :grep

find ./ -type f -exec grep -Hni "some-string" {} ';'

Antwort3

Auf allen aktuellen Unix-Systemen funktioniert es, wenn Sie findzum Suchen der Dateien Folgendes verwenden und dann grepdie Dateien identifizieren, die die folgende Zeichenfolge enthalten foo:

find . -type f -exec grep -l -F -e 'foo' {} +

Der obige Befehl findet alle regulären Dateien im aktuellen Verzeichnis oder darunter. Für Stapel gefundener Dateien grepwird aufgerufen, um die Zeichenfolge zu lokalisieren foo. Beim Lokalisieren der Zeichenfolge in einer Datei grepwird der Pfadname der Datei sofort ausgegeben und mit der nächsten Datei fortgefahren, ohne weiter aus der aktuellen Datei zu lesen.

  • Wir verwenden es, -lum grepden Dateinamen in der ersten Zeile, die dem angegebenen Muster entspricht, anzuhalten und zu melden. Dies beschleunigt die Verarbeitung, indem der Teil der Datei nach dem ersten Treffer ignoriert wird.
  • Wir verwenden es -F, um grepdas Muster als Zeichenfolge und nicht als regulären Ausdruck zu betrachten. Dies beschleunigt möglicherweise die Verarbeitung, da nicht versucht wird, Übereinstimmungen mit regulären Ausdrücken zu finden, und ermöglicht es uns, Zeichenfolgen abzugleichen, die wie reguläre Ausdrücke aussehen.
  • Wir verwenden es -emit dem angegebenen Muster, nur für den Fall, dass es mit einem Bindestrich beginnt. Dies geschieht in diesem Fall nicht, aber das Ersetzen dieser statischen Zeichenfolge foodurch eine Variable würde die Möglichkeit einer Übereinstimmung mit einem Muster eröffnen, das mit einem Bindestrich beginnt und daher für eine Befehlszeilenoption gehalten werden könnte.

Eine Liste von Dateinamen ist jedoch normalerweise nicht gut. Sie möchten wahrscheinlich etwas mit diesen Dateien machen. Wenn ja, würden Sie das als Teil des Dienstprogramms tun, das findausgeführt wird -exec:

find . -type f -exec sh -c '
    for pathname do
        grep -q -F -e "foo" "$pathname" || continue
        # Do something with "$pathname" here
    done' sh {} +

Hier rufen wir ein kurzes Inline-Skript auf, um gefundene Dateien stapelweise zu verarbeiten. Wir prüfen jede Datei einzeln auf die Zeichenfolge foound ignorieren Dateien, die die Zeichenfolge nicht enthalten. Wo ich im Inline-Skript einen Kommentar hinzugefügt habe, würden Sie die mit referenzierte Datei verarbeiten "$pathname".

Sie können das Obige auch mit einer separaten findAusführung grepvor dem Aufruf des Inline-Skripts schreiben:

find . -type f -exec grep -q -F -e 'foo' {} \; -exec sh -c '
    for pathname do
        # Do something with "$pathname" here
    done' sh {} +

Beachten Sie, dass der erste Schritt -execals Test für die aktuelle Datei fungiert, bevor er sh -cmit den Dateien aufgerufen wird, die den Test bestanden haben.

Antwort4

Ich glaube, das ackDienstprogramm wird genau das tun, was Sie suchen. Es ist möglicherweise bereits auf Ihrem System installiert. Wenn nicht, können Sie es hier herunterladen:https://beyondgrep.com/.

Eine der netten Eigenschaften von ackist, dass es standardmäßig Binärdateien ignoriert und Befehlszeilenoptionen bereitgestellt werden können, um die durchsuchten Dateitypen nach einem vorgegebenen Filter oder nach Dateityp einzuschränken (z. B. nach Programmiersprache: --type=ccdurchsucht .c, .h, .xsDateien, --type=awkdurchsucht alle Dateien, die /awk/in der ersten Zeile übereinstimmen). Diese Typen können auch vom Benutzer in der Befehlszeile oder dauerhafter in der ~/.ackrcDatei erweitert werden.

verwandte Informationen