it-swarm.com.de

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 einem gängigen Linux-Rechner, ich habe Bash-Shell:

grep -ircl "foo=" *

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

Ich weiß, dass es die Optionen --exclude=PATTERN und --include=PATTERN gibt, aber wie lautet 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 nach grep include, grep include exclude, grep exclude und Varianten haben nichts Relevantes gefunden

Wenn es eine bessere Möglichkeit gibt, nur in bestimmten Dateien zu greifen, bin ich dafür. Das Verschieben der fehlerhaften Dateien ist keine Option. Ich kann nicht nur bestimmte Verzeichnisse durchsuchen (die Verzeichnisstruktur ist ein großes Durcheinander, mit allem überall). Außerdem kann ich nichts installieren, daher habe ich mit gängigen Tools zu tun (wie grep oder dem vorgeschlagenen find).

739
Piskvor

Verwenden Sie die Shell-Globbing-Syntax:

grep pattern -r --include=\*.{cpp,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 erweitert wird (Anführungszeichen wie --include="*.{cpp,h}" würden genauso gut funktionieren). Wenn sich im aktuellen Arbeitsverzeichnis Dateien befanden, die dem Muster entsprachen, wurde die Befehlszeile auf grep pattern -r --include=foo.cpp --include=bar.h rootdir erweitert, wodurch nur die Dateien mit den Namen foo.cpp und bar.h durchsucht wurden ist ziemlich wahrscheinlich nicht das, was du wolltest.

718
Adam Rosenfield

Wenn Sie nur Binärdateien überspringen möchten, sollten Sie sich die Option -I (i in Großbuchstaben) ansehen. Es ignoriert Binärdateien. Ich benutze regelmäßig den folgenden Befehl:

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

Es sucht rekursiv, ignoriert Binärdateien und sucht nicht in versteckten Ordnern von Subversion nach einem von mir gewünschten Muster. Ich habe es als "grepsvn" auf meiner Box bei der Arbeit aliasiert.

213
rmeador

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

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

wird mit ack als erledigt

ack -icl "foo="

weil ack standardmäßig nie in binären Dateien sucht und -r standardmäßig aktiviert ist. Und wenn Sie nur CPP- und H-Dateien möchten, tun Sie dies einfach

ack -icl --cpp "foo="
63
Andy Lester

grep 2.5.3 hat den Parameter --exclude-dir eingeführt, der so funktioniert, wie Sie es möchten.

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

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

Ich werde an zweiter Stelle Andy's stimmen für ack obwohl es das Beste ist.

34
Corey

Ich habe nach langer Zeit festgestellt, dass Sie mehrere Einschlüsse und Ausschlüsse hinzufügen können, wie zum Beispiel:

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

Der vorgeschlagene Befehl:

grep -Ir --exclude="*\.svn*" "pattern" *

ist konzeptionell falsch, da --exclude mit dem Basisnamen arbeitet. Mit anderen Worten, es wird nur die .svn im aktuellen Verzeichnis übersprungen.

12
Nicola

In grep 2.5.1 müssen Sie diese Zeile zum Profil ~/.bashrc oder ~/.bash hinzufügen

export GREP_OPTIONS="--exclude=\*.svn\*"
11
deric

Ich finde, dass die Ausgabe von grep manchmal sehr hilfreich ist:

grep -rn "foo=" . | grep -v "Binary file"

Das hindert es jedoch nicht daran, die Binärdateien zu durchsuchen.

9
Aaron Maenpaa

Unter CentOS 6.6/Grep 2.6.3 muss ich es folgendermaßen verwenden:

grep "term" -Hnir --include \*.php --exclude-dir "*excluded_dir*"

Beachten Sie das Fehlen von Gleichheitszeichen "=" (andernfalls werden --include, --exclude, include-dir und --exclude-dir ignoriert)

7
aesede

Wenn Sie die Verwendung von find nicht ablehnen, gefällt mir die Funktion -Prune:


find [directory] \
        -name "pattern_to_exclude" -Prune \
     -o -name "another_pattern_to_exclude" -Prune \
     -o -name "pattern_to_INCLUDE" -print0 \
| xargs -0 -I FILENAME grep -IR "pattern" FILENAME

In der ersten Zeile geben Sie das Verzeichnis an, in dem Sie suchen möchten. . (aktuelles Verzeichnis) ist beispielsweise ein gültiger Pfad.

Verwenden Sie in der 2. und 3. Zeile "*.png", "*.gif", "*.jpg" und so weiter. Verwenden Sie so viele dieser -o -name "..." -Prune -Konstrukte, wie Sie Muster haben.

In der vierten Zeile benötigen Sie einen anderen -o (der "oder" für find angibt), die gewünschten Muster und am Ende einen -print oder -print0 . Wenn Sie nur "alles andere" möchten, das nach dem Beschneiden der Bilder *.gif, *.png usw. verbleibt, verwenden Sie -o -print0, und Sie sind mit der 4. Zeile fertig.

Schließlich befindet sich in der 5. Zeile die Pipe zu xargs, die jede dieser resultierenden Dateien aufnimmt und in einer Variablen FILENAME speichert. Anschließend werden grep die Flags -IR und "pattern" übergeben, und dann wird FILENAME um xargs erweitert, um die Liste der von find gefundenen Dateinamen zu werden.

Für Ihre spezielle Frage könnte die Aussage ungefähr so ​​aussehen:


find . \
     -name "*.png" -Prune \
     -o -name "*.gif" -Prune \
     -o -name "*.svn" -Prune \
     -o -print0 | xargs -0 -I FILES grep -IR "foo=" FILES
6
OnlineCop

Ich bin ein Dilettant, aber so sieht mein ~/.bash_profile aus:

 export GREP_OPTIONS = "- orl --exclude-dir = .svn --exclude-dir = .cache --color = auto" GREP_COLOR = '1; 32' 

Beachten Sie, dass ich --exclude-dir zweimal verwenden musste, um zwei Verzeichnisse auszuschließen.

5
4D4M

git grep

Verwenden Sie _git grep_, das für die Leistung optimiert ist und darauf abzielt, bestimmte Dateien zu durchsuchen.

Standardmäßig werden Binärdateien ignoriert und Ihr _.gitignore_ wird gewürdigt. Wenn Sie nicht mit der Git-Struktur arbeiten, können Sie sie trotzdem verwenden, indem Sie _--no-index_ übergeben.

Beispielsyntax:

_git grep --no-index "some_pattern"
_

Weitere Beispiele finden Sie unter:

4
kenorb

Probier diese:

 $ find. -name "* .txt" -Typ f -print | xargs datei | grep "foo =" | cut -d: -f1 

Hier gefunden: http://www.unix.com/Shell-programming-scripting/42573-search-files-excluding-binary-files.html

3
Gravstar

Wenn Sie nicht rekursiv suchen, können Sie Glop-Muster verwenden, um die Dateinamen abzugleichen.

grep "foo" *.{html,txt}

beinhaltet HTML und TXT. Es wird nur im aktuellen Verzeichnis gesucht.

So suchen Sie in den Unterverzeichnissen:

   grep "foo" */*.{html,txt}

In den Unterverzeichnissen:

   grep "foo" */*/*.{html,txt}
3

Schauen Sie sich diesen an.

grep --exclude="*\.svn*" -rn "foo=" * | grep -v Binary | grep -v tags
2
suhas tawade

diese Skripte lösen nicht alle Probleme ... Versuchen Sie es besser:

du -ha | grep -i -o "\./.*" | grep -v "\.svn\|another_file\|another_folder" | xargs grep -i -n "$1"

dieses Skript ist so besser, weil es "echte" reguläre Ausdrücke verwendet, um zu vermeiden, dass Verzeichnisse durchsucht werden. Trennen Sie einfach die Ordner- oder Dateinamen mit "\ |" auf dem grep -v

geniesse es! auf meiner Linux-Shell gefunden! XD

2
villalvilla

In den Verzeichnissen befinden sich auch viele Binärdateien. Ich kann nicht nur bestimmte Verzeichnisse durchsuchen (die Verzeichnisstruktur ist ein großes Durcheinander). Gibt es eine bessere Möglichkeit, nur in bestimmten Dateien zu greifen?

ripgrep

Dies ist eines der schnellsten Tools, mit denen Sie Ihr aktuelles Verzeichnis rekursiv durchsuchen können. Es ist geschrieben in Rust , gebaut auf Rusts Regex-Engine für maximale Effizienz. Überprüfen Sie die detaillierte Analyse hier .

So können Sie einfach laufen:

rg "some_pattern"

Es respektiert Ihren .gitignore und überspringt automatisch versteckte Dateien/Verzeichnisse und Binärdateien.

Sie können weiterhin Dateien und Verzeichnisse mit -g/--glob ein- oder ausschließen. Globbing-Regeln stimmen mit .gitignore Globs überein. Überprüfen Sie man rg auf Hilfe.

Weitere Beispiele finden Sie unter: So schließen Sie einige Dateien aus, die bestimmten Erweiterungen mit grep nicht entsprechen?

Unter macOS können Sie über brew install ripgrep installieren.

2
kenorb

find und xargs sind deine Freunde. Verwenden Sie sie, um die Dateiliste zu filtern, anstatt das --exclude von grep

Versuchen Sie etwas wie

find . -not -name '*.png' -o -type f -print | xargs grep -icl "foo="
2
Andrew Stein

geeignet für tcsh .alias datei:

alias gisrc 'grep -I -r -i --exclude="*\.svn*" --include="*\."{mm,m,h,cc,c} \!* *'

Ich habe eine Weile gebraucht, um herauszufinden, dass der Teil {mm, m, h, cc, c} NICHT in Anführungszeichen stehen sollte. ~ Keith

1
Keith Knauber

Mit der Option --binary-files=without-match zu GNU grep werden Binärdateien übersprungen. (Entspricht dem an anderer Stelle erwähnten Schalter -I.)

(Dies erfordert möglicherweise eine neuere Version von grep; mindestens 2.5.3.)

1
mjs

Um alle binären Ergebnisse von grep zu ignorieren

grep -Ri "pattern" * | awk '{if($1 != "Binary") print $0}'

Der awk-Teil filtert alle Binärdateien für Übereinstimmungen heraus

0
lathomas64