Wie führt man eine Grep-Operation für alle Dateien in einem Verzeichnis durch?

218

Wenn ich mit xenserver arbeite, möchte ich für jede Datei in einem Verzeichnis einen Befehl ausführen, einige Dinge aus der Ausgabe des Befehls entfernen und in eine Datei einfügen.

Ich weiß genau, welchen Befehl ich verwenden möchte und wie ich Zeichenfolgen nach Bedarf abrufen kann.

Was mir jedoch nicht klar ist, ist, wie ich diesen Befehl für jede Datei ausführen soll, um zur nächsten zu gelangen, bis keine Dateien mehr gefunden werden.

user2147075
quelle

Antworten:

228

grep $PATTERN *wäre ausreichend. Standardmäßig überspringt grep alle Unterverzeichnisse. Wenn Sie sie jedoch durchsuchen möchten, grep -r $PATTERN *ist dies der Fall.

umi
quelle
37
"grep -r $ PATTERN." ist ausreichend. Für rekursives grep müssen Sie nicht alle Dateien angeben
Cougar
1
Wie füge ich mehrere Erweiterungen hinzu? Z.B. "* .cpp", "* .h"?
Tomáš Zato - Wiedereinsetzung Monica
1
@ Tomáš Zato, geben Sie einfach alle Ihre Dateimuster anstelle von * : grep $PATTERN *.cpp *.h. Wenn Sie spezifischere Regeln für die zu greifenden Dateien benötigen, verwenden Sie den findBefehl (überprüfen Sie Robs Antwort).
Umi
@umi Wenn ich grep -r x .Ergebnisse ausführe, kommen sie aus allen Dateien aller Erweiterungen. Wenn ich renne, grep -r x *.scsserhalte ich keine Ergebnisse.
Chris
1
@Chris Es ist möglich, dass Sie keine *.scssDateien im aktuellen Verzeichnis haben, sondern irgendwo tiefer in den Unterverzeichnissen, sodass grep nicht in allen gewünschten Dateien sucht. Sie sollten die --includeOption verwenden, um grep anzuweisen, rekursiv nach Dateien zu suchen, die bestimmten Mustern entsprechen: grep -r x --include '*.scss' . (Beachten Sie die Anführungszeichen, sie verhindern, dass das Muster von der Shell erweitert wird.) Oder verwenden Sie einfach find(siehe Robs Antwort).
Umi
168

Unter Linux verwende ich diesen Befehl normalerweise, um rekursiv nach einem bestimmten Text in einem Verzeichnis zu suchen

grep -rni "string" *

wo,

r = rekursiv, dh Unterverzeichnisse im aktuellen Verzeichnis suchen
n =, um die Zeilennummern zu drucken, um stdout
i = Suche ohne Berücksichtigung der Groß- und Kleinschreibung

Narain
quelle
32

Verwenden Sie find. Im Ernst, es ist der beste Weg, denn dann können Sie wirklich sehen, mit welchen Dateien es arbeitet:

find . -name "*.sql" -exec grep -H "slow" {} \;

Beachten Sie, dass -H mac-spezifisch ist und den Dateinamen in den Ergebnissen anzeigt.

rauben
quelle
7
Wenn Sie sich entscheiden , finden zu verwenden, Rohr , durch die Ausgabe xargsanstatt -execdies wird viel schneller, weil -execSpawns für jeden grep einen neuen Prozess, und der Overhead signifikant wird mit einer großen Anzahl von Dateien. Standardwarnungen zu Leerzeichen in Dateinamen gelten für xargs.
Barton Chittenden
2
Wie würde das genau aussehen? Ich vergesse immer die xargsSyntax.
Brian Peterson
3
@ BrianPeterson es wäre so etwas:find . -iname "*.sql" -print0 | xargs -0 grep "slow"
MediaVince
4

Verwenden Sie grep with, um in allen Unterverzeichnissen zu suchen, jedoch nur in bestimmten Dateitypen--include .

Beispiel: Rekursives Suchen im aktuellen Verzeichnis nach Text in * .yml und * .yaml:

grep "text to search" -r . --include=*.{yml,yaml}
Noam Manos
quelle
1

Wenn Sie mehrere Befehle ausführen möchten, können Sie Folgendes verwenden:

for I in `ls *.sql`
do
    grep "foo" $I >> foo.log
    grep "bar" $I >> bar.log
done
Bryan
quelle