Grep Mehrere Verzeichnisse ausschließen CSV funktioniert nicht

503
chris85

Ich versuche, grepfür das Wort world, während alle Verzeichnisse ausschließen, die sind mail, tmpoder .cpanel. Ich kann sie mit dem ignorieren --exclude-dir=name, aber beim Lesen anderer Threads scheint es mir möglich zu sein, eine durch Kommas getrennte Liste zu verwenden. Ich hatte jedoch kein Glück beim Versuch:

grep 'world' --exclude-dir={./mail,./.cpanel,./tmp} -ri . 

und

grep 'world' --exclude-dir= -ri . 

als keine Arbeit. Die Verwendung --exclude-dirmit nur einem Verzeichnis funktioniert wie in:

grep 'world' --exclude-dir=mail -ri . 

aber ich zurück tmpkann .cpanelAngebote.

Wie kann ich alle Verzeichnisse in einem Befehl angeben (sobald ich das .cpanelund das tmpausgeschlossen habe, vermute ich, dass es noch ein paar irrelevante Verzeichnisse gibt, daher möchte ich kein Verzeichnis --exclude-dir).

1

2 Antworten auf die Frage

2
bertieb

exclude-dirist grepversionsabhängig

Die Flagge wurde eingeführt wurde mit> 2.5.2 eingeführt :

+ Version 2.5.2 + - Mit der neuen Option --exclude-dir kann ein Verzeichnismuster angegeben werden  + das wird vom rekursiven grep ausgeschlossen.

(H / T zu Johnsywebs Antwort auf SO, um die Version herauszufinden )

Wo implementiert, funktioniert es als normale, durch Kommas getrennte Liste von Verzeichnissen, die ausgeschlossen werden sollen, ohne Leerzeichen:

$ grep 'foo' -ri .  ./a/test.txt:foo bar baz ./c/test.txt:foo bar baz ./b/test.txt:foo bar baz  $ grep 'foo' --exclude-dir= -ri .  ./c/test.txt:foo bar baz 

Alternativ, wenn Ihre Version von grepnicht unterstützt wird {}und Sie nicht weiterhin Verzeichnisse eingeben müssen

Fügen Sie die Verzeichnisse in ein Array ein und erweitern Sie das in den Befehl:

$ exclude=( "mail" ".cpanel" "tmp" ) $ for dir in $; do echo "--exclude-dir=$dir"; done  --exclude-dir=mail --exclude-dir=.cpanel --exclude-dir=tmp 

Verwenden Sie wie folgt:

$ grep 'world' $(for dir in $; do echo "--exclude-dir=$dir"; done) -ri . 

Erläuterung : Die Ersetzung $()setzt Ihre --exclude-dirArgumente als Argumente für grep ein grep.

Ich habe mich beim Testen irgendwie geirrt. Mein ursprünglicher "grep" funktioniert jetzt. Es tut uns leid. Danke für deine Antwort. chris85 vor 7 Jahren 1
Ich weiß nicht, auch wenn Sie sich vermasselt haben, ist dies eine plausible Antwort für andere Leute und ist ziemlich gut geschrieben. Fühlt sich wie ein bisschen Verschwendung an, um diese und @ TOOGAMs Antwort zu löschen. Ich schlage vor, die beste als richtige Antwort zu wählen und angemessen über das Löschen zu stimmen. Journeyman Geek vor 7 Jahren 2
Vielen Dank für das Feedback - es kann in Zukunft denjenigen helfen, für die es tatsächlich * nicht * funktioniert (weil sie auf * BSD sind oder alte Versionen ausführen). Prost! bertieb vor 7 Jahren 1
2
TOOGAM

Abhängig von Ihrer Definition des Befehls kann Folgendes möglicherweise eine korrekte Antwort sein:

grep -iR 'world' . | grep -v mail | grep -v ".cpanel" | grep -v tmp

(Eigentlich bin ich ziemlich sicher, dass ".cpanel" keine Anführungszeichen benötigt. Aber ich neige dazu, die Dinge sicher zu spielen, anstatt mich an all die Nuancen zu erinnern, wenn es irgendwelche Interpunktionen gibt, neige ich dazu, es zu zitieren.)

Wenn Ihre Definition von "Befehl" lautet, wenn eine ausführbare Datei angegeben wird, handelt es sich um vier Befehle, die die Frage nicht beantworten. Wenn Ihre Definition von "Befehl" jedoch auf der Grundlage der Eingabe von "Eingabe" basiert oder wenn Sie sagen, dass 5 Befehle vorhanden sind (ein Befehl, der 4 weitere Befehle enthält), habe ich erfolgreich einen einzigen Befehl bereitgestellt, der das tut, was Sie tun fragte. (Anstatt sich auf eine GNU-Erweiterung namens --exclude-dir zu verlassen, funktioniert dieser Ansatz jedoch auf mehr Betriebssystemen.)

`grep -v mail` schließt jedoch jeden` ​​mail'-Kontext aus, oder? Ich möchte es nur begrenzen, wenn es sich um ein Verzeichnis handelt. chris85 vor 7 Jahren 1
Ah, Sie möchten, dass grep alle Verzeichnisse außer den begrenzten durchsucht. Hmm, bertiebs Antwort könnte dafür besser sein. Um nur ungefähr zu zeigen, wie dies mit dem von mir genannten Ansatz geschehen würde, vielleicht: `grep -ri" world "$ (find. -Type -maxdepth 0 | grep -Ev ^ [.] $ | Grep -v mail | grep -v .cpanel | grep -v tmp | xargs) `# Das" grep -Ev ^ [.] $ "entfernt die Zeile, die nur einen Punkt enthält, so dass Unterverzeichnisse geprüft werden TOOGAM vor 7 Jahren 1