
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 grep
in 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 -l
nur den Dateinamen ausgeben:
grep -lR foo /path/to/parent/directory
Beachten Sie, dass die -R
Option nicht portierbar ist und nicht von allen grep
Implementierungen unterstützt wird.
Antwort2
Wenn grep -R
dies keine Option ist, können Sie für jede Datei find
Folgendes ausführen :grep
find ./ -type f -exec grep -Hni "some-string" {} ';'
Antwort3
Auf allen aktuellen Unix-Systemen funktioniert es, wenn Sie find
zum Suchen der Dateien Folgendes verwenden und dann grep
die 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 grep
wird aufgerufen, um die Zeichenfolge zu lokalisieren foo
. Beim Lokalisieren der Zeichenfolge in einer Datei grep
wird der Pfadname der Datei sofort ausgegeben und mit der nächsten Datei fortgefahren, ohne weiter aus der aktuellen Datei zu lesen.
- Wir verwenden es,
-l
umgrep
den 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
, umgrep
das 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
-e
mit 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 Zeichenfolgefoo
durch 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 find
ausgefü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 foo
und 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 find
Ausführung grep
vor 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 -exec
als Test für die aktuelle Datei fungiert, bevor er sh -c
mit den Dateien aufgerufen wird, die den Test bestanden haben.
Antwort4
Ich glaube, das ack
Dienstprogramm 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 ack
ist, 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=cc
durchsucht .c
, .h
, .xs
Dateien, --type=awk
durchsucht alle Dateien, die /awk/
in der ersten Zeile übereinstimmen). Diese Typen können auch vom Benutzer in der Befehlszeile oder dauerhafter in der ~/.ackrc
Datei erweitert werden.