Ich suche die Zeichenfolge foo=
in Textdateien in einem Verzeichnisbaum. Es ist auf einem gemeinsamen Linux-Computer, 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 die Suche in diesen Dateien überspringt (hauptsächlich JPEG- und PNG-Bilder). Wie würde ich das machen?
Ich weiß, dass es die --exclude=PATTERN
und --include=PATTERN
Optionen gibt, aber wie 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.
Die Suche auf grep include , grep include exclude , grep exclude und Varianten hat nichts Relevantes gefunden
Wenn es eine bessere Möglichkeit gibt, nur in bestimmten Dateien zu greifen, bin ich alles 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 Fund ).
--exclude-dir=.svn
, dass Grep überhaupt nicht daraufgrep -r --exclude-dir=var "pattern" .
Antworten:
Verwenden Sie die Shell-Globbing-Syntax:
Die Syntax für
--exclude
ist identisch.Beachten Sie, dass der Stern mit einem Backslash versehen wird, um zu verhindern, dass er von der Shell erweitert wird (wenn Sie ihn zitieren
--include="*.{cpp,h}"
, würde dies genauso gut funktionieren). Wenn Sie andernfalls Dateien im aktuellen Arbeitsverzeichnis hätten, die dem Muster entsprechen, würde die Befehlszeile so erweitertgrep pattern -r --include=foo.cpp --include=bar.h rootdir
, dass nur Dateien mit dem Namen durchsucht werdenfoo.cpp
undbar.h
was höchstwahrscheinlich nicht das ist, was Sie wollten.quelle
grep pattern -r --include="*.{cpp,h}" rootdir
grep pattern -r --include=foo.cpp --include=bar.h rootdir
, in der nur Dateien durchsucht werden benanntfoo.cpp
oderbar.h
. Wenn Sie keine Dateien haben, die mit dem Glob im aktuellen Verzeichnis übereinstimmen, gibt die Shell den Glob an grep weiter, der ihn korrekt interpretiert.--exclude-dir
Option. Es gelten jedoch die gleichen Regeln. Es wird nur der Verzeichnisdateiname abgeglichen, kein Pfad.--include
scheint danach nicht zu funktionieren--exclude
. Ich nehme an, es macht keinen Sinn, es überhaupt zu versuchen, außer dass ichalias
eine lange Liste von--exclude
und haben muss--exclude-dir
, die ich zum Durchsuchen von Code, Ignorieren von Bibliotheken und Austauschen von Dateien und Dingen verwende. Ich hätte gehofft, dassgrep -r --exclude='*.foo' --include='*.bar'
das funktionieren würde, also könnte ich michalias
auf--include='*.bar'
nur beschränken, aber es scheint das zu ignorieren--include
und alles einzuschließen, was keine .foo-Datei ist. Das Vertauschen der Reihenfolge von--include
und--exclude
funktioniert, aber leider ist das bei mir nicht hilfreichalias
.PATTERN
. Eine halbe Stunde kann ich keine Beschreibung finden, worauf sie dort wartenWenn Sie nur Binärdateien überspringen möchten, empfehlen wir Ihnen die
-I
Option (Großbuchstaben i). Binärdateien werden ignoriert. Ich benutze regelmäßig den folgenden Befehl:Es sucht rekursiv, ignoriert Binärdateien und sucht nicht in versteckten Subversion-Ordnern nach dem gewünschten Muster. Ich habe es als "grepsvn" auf meiner Box bei der Arbeit aliased.
quelle
--exclude-dir
ist nicht überall verfügbar. Meine RH-Box bei der Arbeit mit GNU grep 2.5.1 hat es nicht.--exclude-dir
es nicht verfügbar ist? In all meinen Versuchen--exclude
scheint nicht die Rechnung zu passen.--exclude-dir="\.git"
. :-)Bitte werfen Sie einen Blick auf ack , das genau für diese Situationen ausgelegt ist. Ihr Beispiel von
wird mit ack as gemacht
weil ack standardmäßig nie in Binärdateien sucht und -r standardmäßig aktiviert ist. Und wenn Sie nur CPP- und H-Dateien möchten, tun Sie dies einfach
quelle
apt-get
in Ubuntu :)awk
In grep 2.5.3 wurde der Parameter --exclude-dir eingeführt, der wie gewünscht funktioniert.
Sie können auch eine Umgebungsvariable festlegen: GREP_OPTIONS = "- exclude-dir = .svn"
Ich werde Andys Stimme für ack unterstützen , es ist das Beste.
quelle
Ich fand dies nach langer Zeit, Sie können mehrere Ein- und Ausschlüsse hinzufügen wie:
quelle
Der vorgeschlagene Befehl:
ist konzeptionell falsch, weil --exclude für den Basisnamen funktioniert. Mit anderen Worten, es wird nur die .svn im aktuellen Verzeichnis übersprungen.
quelle
In grep 2.5.1 müssen Sie diese Zeile zum Profil ~ / .bashrc oder ~ / .bash hinzufügen
quelle
Ich finde die Ausgabe von grepping grep manchmal sehr hilfreich:
Das hindert es jedoch nicht daran, die Binärdateien zu durchsuchen.
quelle
grep -I
Binärdateien überspringen.Wenn Sie nicht abgeneigt sind
find
, mag ich seine-prune
Funktion:In der ersten Zeile geben Sie das Verzeichnis an, nach dem Sie suchen möchten.
.
(aktuelles Verzeichnis) ist beispielsweise ein gültiger Pfad.Am 2. und 3. Zeile, Verwendung
"*.png"
,"*.gif"
,"*.jpg"
und so weiter. Verwenden Sie so viele dieser-o -name "..." -prune
Konstrukte, wie Sie Muster haben.In der 4. Zeile benötigen Sie ein anderes
-o
(es gibt "oder" bisfind
) an, die Muster, die Sie möchten, und Sie benötigen entweder ein-print
oder-print0
am Ende. Wenn Sie nur wollen „alles andere“ , die Überreste nach dem Beschneiden der*.gif
,*.png
usw. Bilder, dann verwenden-o -print0
und Sie sind mit der 4. Zeile getan.Schließlich befindet sich in der 5. Zeile die Pipe, zu
xargs
der jede dieser resultierenden Dateien genommen und in einer Variablen gespeichert wirdFILENAME
. Es übergibt danngrep
die-IR
Flags,"pattern"
und wird dann um die Liste der DateinamenFILENAME
erweitertxargs
, die von gefunden wurdenfind
.Für Ihre spezielle Frage könnte die Aussage ungefähr so aussehen:
quelle
-false
sofort nach jedem ein,-prune
damit das Vergessen der Verwendung-print0
oder einexec
Befehl die Dateien, die Sie ausschließen wollten, nicht druckt:-name "*.png" -prune -false -o name "*.gif -prune -false
...Unter CentOS 6.6 / Grep 2.6.3 muss ich es folgendermaßen verwenden:
Beachten Sie die fehlende Gleichheitszeichen „=“ (sonst
--include
,--exclude
,include-dir
und--exclude-dir
ignoriert werden)quelle
git grep
Verwendung,
git grep
die für die Leistung optimiert ist und darauf abzielt, bestimmte Dateien zu durchsuchen.Standardmäßig werden Binärdateien ignoriert und Ihre
.gitignore
. Wenn Sie nicht mit der Git-Struktur arbeiten, können Sie sie trotzdem durch Übergeben verwenden--no-index
.Beispielsyntax:
Weitere Beispiele finden Sie unter:
quelle
Zugegeben, ich bin ein Dilettant, aber so sieht mein ~ / .bash_profile aus:
Beachten Sie, dass ich --exclude-dir zweimal verwenden musste, um zwei Verzeichnisse auszuschließen.
quelle
Probier diese:
Hier gegründet: http://www.unix.com/shell-programming-scripting/42573-search-files-excluding-binary-files.html
quelle
Wenn Sie nicht rekursiv suchen, können Sie Glop-Muster verwenden , um die Dateinamen abzugleichen .
enthält HTML und TXT. Es wird nur im aktuellen Verzeichnis gesucht.
So suchen Sie in den Unterverzeichnissen:
In den Unterverzeichnissen:
quelle
ripgrep
Dies ist eines der schnellsten Tools zum rekursiven Durchsuchen Ihres aktuellen Verzeichnisses. Es ist in Rust geschrieben und basiert auf Rusts Regex-Motor für maximale Effizienz. Überprüfen Sie die detaillierte Analyse hier .
Sie können also einfach ausführen:
Es respektiert Ihre
.gitignore
und überspringt automatisch versteckte Dateien / Verzeichnisse und Binärdateien.Sie können das Einschließen oder Ausschließen von Dateien und Verzeichnissen weiterhin mit
-g
/ anpassen--glob
. Globbing-Regeln stimmen mit.gitignore
Globs überein. Suchen Sieman rg
nach Hilfe.Weitere Beispiele finden Sie unter: Wie kann ich einige Dateien ausschließen, die bestimmten Erweiterungen nicht mit grep entsprechen?
Unter macOS können Sie über installieren
brew install ripgrep
.quelle
find und xargs sind deine Freunde. Verwenden Sie sie, um die Dateiliste zu filtern, anstatt greps --exclude
Versuchen Sie etwas wie
Der Vorteil, sich daran zu gewöhnen, besteht darin, dass es auf andere Anwendungsfälle erweitert werden kann, z. B. um die Zeilen in allen Nicht-PNG-Dateien zu zählen:
So entfernen Sie alle Nicht-PNG-Dateien:
usw.
Wie in den Kommentaren erwähnt, verwenden Sie stattdessen
-print0
und , wenn einige Dateien Leerzeichen in ihren Namen habenxargs -0
.quelle
Diese Skripte lösen nicht das ganze Problem ... Versuchen Sie es besser:
Dieses Skript ist so besser, weil es "echte" reguläre Ausdrücke verwendet, um Verzeichnisse bei der Suche zu vermeiden. Trennen Sie einfach Ordner- oder Dateinamen mit "\ |" auf dem grep -v
geniesse es! auf meiner Linux-Shell gefunden! XD
quelle
Schau mal bei diesem.
quelle
Mit der
--binary-files=without-match
Option zu GNUgrep
können Binärdateien übersprungen werden. (Entspricht dem an-I
anderer Stelle genannten Schalter.)(Dies erfordert möglicherweise eine neuere Version von
grep
; 2.5.3 hat es zumindest.)quelle
geeignet für tcsh .alias Datei:
Ich habe eine Weile gebraucht, um herauszufinden, dass der Teil {mm, m, h, cc, c} NICHT in Anführungszeichen stehen sollte. ~ Keith
quelle
Alle binären Ergebnisse von grep ignorieren
Der awk-Teil filtert alle Foo-Übereinstimmungszeilen der Binärdatei heraus
quelle
Versuche dies:
--F
" unter currdir .. (oder verknüpfen Sie einen anderen Ordner, der dort in "--F
" umbenannt wurde)double-minus-F
.#> grep -i --exclude-dir="\-\-F" "pattern" *
quelle