Ich möchte die Datei ./test/main.cpp
von meiner Suche ausschließen.
Folgendes sehe ich:
$ grep -r pattern --exclude=./test/main.cpp
./test/main.cpp:pattern
./lib/main.cpp:pattern
./src/main.cpp:pattern
Ich weiß, dass es möglich ist, die gewünschte Ausgabe mit mehreren Befehlen in einer Pipes-and-Filters-Anordnung zu erhalten, aber gibt es einige Anführungszeichen / Escapezeichen, die grep
verstehen lassen , was ich von Haus aus will?
command-line
grep
kein Balken
quelle
quelle
--exclude-dir
) ausschließen möchte . Deshalb möchte ich grep den Ausschluss nativ ausführen lassen.Antworten:
grep
Dies ist für Dateien in einem bestimmten Verzeichnis nicht möglich, wenn Sie mehrere Dateien mit demselben Namen in verschiedenen Verzeichnissen haben. Verwenden Sie stattdessen find:find . -type f \! -path './test/main.cpp' -exec grep pattern {} \+
quelle
\!
und\+
? Es scheint gut zu funktionieren, ohne die Backslashes.grep
kann das nicht,find
stattdessen verwenden" - perfekt.Ich denke nicht, dass es mit GNU möglich ist
grep
. Du brauchst aber keine Rohre.Mit
find
:Mit
zsh
:(Ausgeschlossen sind versteckte Dateien, ebenso das .git, .svn ...).
quelle
Ich könnte ein Buch schreiben: "Die verlorene Kunst von
xargs
". Dasfind ... -exec … ';
startet ein Grep für jede Datei (aber die Variante mit-exec … +
nicht). Nun, wir verschwenden heutzutage CPU-Zyklen. Warum also nicht? Aber wenn Leistung, Gedächtnis und Energie ein Problem sind: benutze xargs:GNU
find
‚s-print0
wirdNUL
seine Ausgabe und -terminatexargs
‘-0
Option ehrt das Format als Eingabe. Dadurch wird sichergestellt, dass die Pipeline nicht durcheinander gerät, unabhängig davon, welche lustigen Zeichen Ihre Datei enthält. Die-r
Option stellt sicher, dass kein Fehler vorliegt, fallsfind
nichts gefunden wird.Beachten Sie, dass Sie jetzt Folgendes ausführen können:
GNU grep
-z
macht dasselbe wie xargs-0
.quelle
find -exec (cmd) {} +
funktioniert es genauso wiexargs
undfind -exec (cmd) {} \;
funktioniert genauso wiexargs -n1
. Mit anderen Worten, Ihre Aussage ist nur richtig, wenn die\;
Version verwendet wird.xargs
ist weniger effizient als das Verwenden-exec … +
(wenn auch nur geringfügig). Keine der Antworten hier erwähnt auch nur-exec … \;
.-exec ... +
hinzugefügt im Januar 2005. Ja, ich bin nicht veraltet ... überhaupt ....Wenn Ihre
find
Unterstützungen,-path
die 2008 zu POSIX hinzugefügt wurden, in Solaris jedoch noch fehlen:quelle
-path
ist nicht POSIX?Für die Aufzeichnung ist hier der Ansatz, den ich bevorzuge:
grep
Ich halte das am Anfang des Befehls, was meiner Meinung nach ein wenig klarer ist - außerdem wird die Farbhervorhebung nicht deaktiviertgrep
. In gewissem Sinne ist die Verwendungfind
in einer Befehlsersetzung nur eine Möglichkeit, die (begrenzte) Dateisuchteilmenge dergrep
Funktionalität von zu erweitern / zu ersetzen .Für mich ist die
find -exec
Syntax irgendwie arkan. Eine Schwierigkeitfind -exec
ist die (manchmal) Notwendigkeit, verschiedene Zeichen zu maskieren (insbesondere, wenn\;
sie unter Bash verwendet werden). Nur um die Dinge in einen vertrauten Kontext zu bringen, sind die folgenden zwei Befehle im Grunde gleichbedeutend:Wenn Sie Unterverzeichnisse ausschließen möchten , müssen Sie möglicherweise einen Platzhalter verwenden. Ich verstehe das Schema hier nicht ganz - rede über Arkan :
Ein weiterer Hinweis zur Verallgemeinerung von
find
Lösungen zur Verwendung in Skripten : Diegrep
Befehlszeile sollte die Option-H
/ enthalten--with-filename
. Andernfalls wird die Ausgabeformatierung geändert, wenn die Suchergebnisse von nur einen Dateinamen enthaltenfind
. Dies ist bemerkenswert, da es bei Verwendunggrep
der nativen Dateisuche (mit der-r
Option) nicht erforderlich zu sein scheint .... Noch besser ist es jedoch,
/dev/null
als erste zu durchsuchende Datei einzuschließen. Dies löst zwei Probleme:grep
zwei Dateien vorhanden sind und der Ausgabemodus für mehrere Dateien verwendet wird.grep
wird, dass eine Datei vorhanden ist, und das Warten auf stdin nicht unterbrochen wird.Die endgültige Antwort lautet also:
quelle
find
in einer Befehlsersetzung verwenden. Dies bricht ab, wenn Dateinamen Leerzeichen oder andere Sonderzeichen enthalten. Verwendungfind -exec
, es ist robust und einfach zu bedienen.find -iname "*target*" -or -name 'exclude' -prune
. Nun, es funktioniert irgendwie - das beschnittene Verzeichnis wird aufgelistet, aber nicht durchsucht. Wenn Sie nicht möchten, dass es aufgeführt wird, können Sie eine Art redundantes! -name 'exclude'