926 Stimmen

Verwenden Sie die Syntax grep --exclude/--include, um bestimmte Dateien nicht zu durchsuchen

Ich suche nach der Zeichenfolge foo= in Textdateien in einem Verzeichnisbaum. Es ist auf einer gemeinsamen Linux-Maschine, ich habe Bash-Shell:

grep -ircl "foo=" *

In den Verzeichnissen befinden sich auch viele Binärdateien, die mit "foo=" . Da diese Ergebnisse nicht relevant sind und die Suche verlangsamen, möchte ich, dass grep die Suche in diesen Dateien (meist JPEG- und PNG-Bilder) überspringt. Wie würde ich das machen?

Ich weiß, es gibt die --exclude=PATTERN y --include=PATTERN Optionen, aber was ist das Musterformat? Die Manpage von grep sagt:

--include=PATTERN     Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN     Recurse in directories skip file matching PATTERN.

Suche auf grep include , grep include exclude , grep ausschließen und Varianten haben nichts Relevantes gefunden

Wenn es eine bessere Möglichkeit gibt, nur bestimmte Dateien zu durchsuchen, bin ich dafür; das Verschieben der betreffenden Dateien ist keine Option. Ich kann nicht nur bestimmte Verzeichnisse durchsuchen (die Verzeichnisstruktur ist ein großes Durcheinander, mit allem, was überall ist). Außerdem kann ich nichts installieren, so dass ich mit den üblichen Tools auskommen muss (wie grep oder die vorgeschlagene finden. ).

14 Stimmen

Nur zu Ihrer Information: die verwendeten Argumente: -c Zählen der Übereinstimmungen in der Datei -i Groß-/Kleinschreibung nicht beachten -l Nur passende Dateien anzeigen -r Rekursiv

73 Stimmen

Ein schnellerer Weg, svn-Verzeichnisse auszuschließen, ist --exclude-dir=.svn so dass grep gar nicht in sie hineingeht

26 Stimmen

Ein paar pedantische Punkte, die man vielleicht wissen sollte: 1. Beachten Sie das Fehlen von Anführungszeichen um den glob hier: --exclude=' .{png,jpg}' funktioniert nicht (zumindest mit meiner GNU grep-Version), weil grep keine {} in seinen Globs unterstützt. Die obige Shell-Erweiterung ist '--exclude= .png --exclude=*.jpg' (unter der Annahme, dass keine Dateien im cwd übereinstimmen - was sehr unwahrscheinlich ist, da man Dateinamen normalerweise nicht mit '--exclude=' beginnt), was grep sehr gut gefällt. 2. --exclude ist eine GNU-Erweiterung und nicht Teil der POSIX-Definition von grep. Wenn Sie also Skripte schreiben, die dies verwenden, sollten Sie sich bewusst sein, dass sie nicht unbedingt auf Nicht-GNU-Systemen laufen.

943voto

Adam Rosenfield Punkte 373807

Verwenden Sie die Shell Globbing-Syntax :

grep pattern -r --include=\*.cpp --include=\*.h rootdir

Die Syntax für --exclude ist identisch.

Beachten Sie, dass der Stern mit einem Backslash maskiert wird, um zu verhindern, dass er von der Shell expandiert wird (durch Anführungszeichen, wie --include="*.cpp" würde genauso gut funktionieren). Andernfalls, wenn sich im aktuellen Arbeitsverzeichnis Dateien befinden, die dem Muster entsprechen, würde sich die Befehlszeile zu etwas wie grep pattern -r --include=foo.cpp --include=bar.cpp rootdir , die nur Dateien mit dem Namen foo.cpp y bar.cpp was höchstwahrscheinlich nicht das ist, was Sie wollten.

Aktualisierung 2021-03-04

Ich habe die ursprüngliche Antwort bearbeitet, um die Verwendung von Spreizung Dies ist eine Funktion, die von mehreren Shells wie Bash und zsh zur Verfügung gestellt wird, um Muster wie dieses zu vereinfachen; beachten Sie jedoch, dass die Klammererweiterung nicht POSIX-Shell-konform ist.

Das ursprüngliche Beispiel war:

grep pattern -r --include=\*.{cpp,h} rootdir

zum Durchsuchen aller .cpp y .h Dateien, die im Verzeichnis rootdir .

12 Stimmen

Ich weiß nicht, warum, aber ich musste das Include-Muster so zitieren: grep pattern -r --include="*.{cpp,h}" rootdir

6 Stimmen

@topek: Guter Punkt -- wenn Sie irgendwelche .cpp/.h-Dateien in Ihrem aktuellen Verzeichnis haben, dann wird die Shell den glob expandieren, bevor sie grep aufruft, so dass Sie am Ende eine Befehlszeile erhalten wie grep pattern -r --include=foo.cpp --include=bar.h rootdir die nur Dateien mit dem Namen foo.cpp o bar.h . Wenn sich im aktuellen Verzeichnis keine Dateien befinden, die dem glob entsprechen, gibt die Shell den glob an grep weiter, das ihn korrekt interpretiert.

7 Stimmen

Ich habe gerade festgestellt, dass der glob nur für den Dateinamen verwendet wird. Um ein ganzes Verzeichnis auszuschließen, braucht man --exclude-dir Option. Es gelten jedoch dieselben Regeln. Es wird nur der Dateiname des Verzeichnisses abgeglichen, nicht der Pfad.

237voto

rmeador Punkte 25087

Wenn Sie nur die Binärdateien überspringen wollen, sollten Sie sich die -I (Großbuchstabe i) zu wählen. Sie ignoriert Binärdateien. Ich verwende regelmäßig den folgenden Befehl:

grep -rI --exclude-dir="\.svn" "pattern" *

Es sucht rekursiv, ignoriert Binärdateien und sucht nicht in versteckten Subversion-Ordnern nach dem von mir gewünschten Muster. Ich habe es als "grepsvn" auf meinem Rechner bei der Arbeit angemeldet.

27 Stimmen

--exclude-dir ist nicht überall verfügbar. Meine RH-Box auf der Arbeit mit GNU grep 2.5.1 hat es nicht.

0 Stimmen

Irgendwelche Vorschläge, was zu verwenden ist, wenn --exclude-dir nicht verfügbar ist? Bei all meinen Versuchen, --exclude scheint nicht in Frage zu kommen.

1 Stimmen

Sie können jederzeit die neuesten grep-Quellen von GNU herunterladen und ein 'configure; make; sudo make install' durchführen. Dies ist eines der ersten Dinge, die ich auf einem Mac oder einer älteren Linunx-Distribution mache.

73voto

Andy Lester Punkte 86147

Schauen Sie sich bitte an ack das für genau diese Situationen konzipiert ist. Ihr Beispiel von

grep -ircl --exclude=*.{png,jpg} "foo=" *

erfolgt mit ack als

ack -icl "foo="

weil ack standardmäßig nie in Binärdateien sucht und -r standardmäßig eingeschaltet ist. Und wenn Sie nur CPP- und H-Dateien wollen, dann machen Sie einfach

ack -icl --cpp "foo="

37voto

Corey Punkte 559

Grep 2.5.3 führte die Funktion --exclude-dir der so funktioniert, wie Sie es wünschen.

grep -rI --exclude-dir=\.svn PATTERN .

Sie können auch eine Umgebungsvariable setzen: GREP_OPTIONS="--exclude-dir=\.svn"

Ich unterstütze Andys Stimme für ack Aber es ist das Beste.

33voto

Rushabh Mehta Punkte 1353

Nach langer Zeit habe ich herausgefunden, dass man mehrere Ein- und Ausschlüsse hinzufügen kann:

grep "z-index" . --include=*.js --exclude=*js/lib/* --exclude=*.min.js

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X