Ich versuche, alle Dateien zu finden, die von einem bestimmten Typ sind und keine bestimmte Zeichenfolge enthalten. Ich versuche, es zu tun, indem ich find auf grep -v leite
Beispiel:
find -type f -name '*.java' | xargs grep -v "something something"
Das scheint nicht zu funktionieren. Es scheint nur die Dateien zurückzugeben, die der Befehl find gefunden hat. Was ich versuche, ist im Grunde alle .java-Dateien zu finden, die einem bestimmten Dateinamen entsprechen (zB endet mit 'Pb' wie in SessionPb.java) und die kein 'erweitertes SomethingSomething' enthalten.
Mein Verdacht ist, dass ich es falsch mache. Wie sollte der Befehl stattdessen aussehen?
Antworten:
Hier gibt es keine Notwendigkeit
xargs
. Außerdem müssen Sie die Optiongrep
with-L
(Dateien ohne Übereinstimmung) verwenden, da ansonsten der Dateiinhalt anstelle des Namens ausgegeben wird, wie in Ihrem Beispiel.quelle
-L
hat schon verhandlungen, weil es heißtfiles _without_ match
. Daher brauchen Sie-v
hier keine Option.xargs
ist viel, viel besser alsfind
+-exec
. Ersteres erstellt einengrep
Prozess, der alle Dateien als Argumente abruft, während letzteresgrep
für jede Datei einmal ausgeführt wird.-exec ... {} \+
entspricht nichtxargs
. Bitte lesen Sie die findutils Dokumentation! (Ich habe ziemlich hart daran gearbeitet!)xargs
die Eingabe verarbeitet und die Argumente in Leerzeichen getrennt werden. Anführungszeichen gelten auch speziell (standardmäßig) fürxargs
. Keines dieser Dinge ist wahr für-exec ... {} +
. In alten Versionen wurdexargs
der Unterstrich als EOF-Indikator verwendet, dies ist jedoch nicht mehr der Fall.Du hast es wirklich fast geschafft ...
Der Punkt '.' sagt, von hier aus zu beginnen. (deins impliziert es .. aber nimm niemals an).
-iname verwendet die Suche ohne Berücksichtigung der Groß- und Kleinschreibung, nur für den Fall (oder nur für den Fall, dass dies nicht der Fall ist).
-print0 sendet Dateinamen mit einem nachgestellten \ x00-Zeichen an xargs, wodurch Probleme mit Dateinamen mit Leerzeichen vermieden werden.
Die '-0' in xargs gibt an, dass Dateinamen mit \ x00 anstelle von Rückgaben enden sollen.
und dein grep Befehl ...
So ziemlich alles verstanden.
BEARBEITEN::
Von Ihrem Update:
sollte helfen. (Hinzugefügt -L von @ Ansturm Antwort, gute Arbeit)
Ich habe die Idee, dass Ihr grep entweder die Option '-i' benötigt oder weniger explizit sein soll.
Versuchen Sie den Befehl in Teilen ... Gibt DIESE Dateinamen richtig aus?
Wenn ja, dann stimmt Ihr Problem wahrscheinlich entweder nicht mit Ihrem Suchmuster überein (Rechtschreibfehler? Es passiert!) Oder es gibt einfach keine Übereinstimmungen.
Absolut schlimmster Fall:
Ich werde viel mehr arbeiten, um alles zu durchsuchen, aber ich sollte Ihnen eine Ausgabe geben.
quelle
xargs -0 grep -v "something something"
sein sollte ,xargs -0 grep -v "something something" /dev/null
sonst werden Sie ungeradee Ergebnisse erhalten , wenn finde keine passenden Dateien erzeugt.Der Computer ist ein Computer: Er tut, was Sie ihm befohlen haben, anstatt das zu tun, was Sie von ihm wollten.
grep -v "something something"
druckt alle Zeilen, die nicht enthaltensomething something
. Beispielsweise werden zwei der folgenden drei Zeilen gedruckt:extends SomethingSomething
Verwenden Sie die folgende-L
Option, um Dateien zu drucken, die nirgendwo enthalten :Einige Versionen von grep verfügen nicht über die
-L
Option (sie wird von POSIX nicht angegeben ). Wenn dies nicht der Fall ist, lassen Sie es nichts drucken und den Rückkehrcode verwenden, damit die aufrufende Shell das tut, was sie tun soll.Alternativ können Sie awk verwenden.
Unter Linux oder Cygwin (oder einem anderen System mit GNU grep) müssen Sie es nicht verwenden
find
, dagrep
es sich um ein rekursives System handelt.Wenn Ihre Shell ksh oder bash oder zsh ist, können Sie die Shell veranlassen, den Dateinamen abzugleichen. Bei Bash
set -o globstar
zuerst ausführen (Sie können dies in Ihre einfügen~/.bashrc
).quelle
\s
ist eine GNU grep Erweiterung, mit der ich gleichbedeutend bin[[:space:]]
.