Vielleicht möchten Sie Anrufe verketten, um zu finden (einmal, als Sie erfuhren, dass es möglich ist, was heute sein könnte). Dies ist natürlich nur möglich, solange Sie in find bleiben. Sobald Sie eine Pipe an xargs gesendet haben, ist dies nicht mehr möglich.
Kleines Beispiel, zwei Dateien a.lst und b.lst:
cat a.lst
fuddel.sh
fiddel.sh
cat b.lst
fuddel.sh
Kein Trick hier - einfach die Tatsache, dass beide "Fuddel" enthalten, aber nur eine "Fiddel" enthält.
Angenommen, wir wüssten das nicht. Wir suchen eine Datei, die 2 Bedingungen entspricht:
find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls
192097 4 -rw-r--r-- 1 stefan stefan 20 Jun 27 17:05 ./a.lst
Nun, vielleicht kennen Sie die Syntax für grep oder ein anderes Programm, um beide Zeichenfolgen als Bedingung zu übergeben, aber das ist nicht der Punkt. Jedes Programm, das true oder false zurückgeben kann, wenn eine Datei als Argument angegeben wird, kann hier verwendet werden - grep war nur ein beliebtes Beispiel.
Beachten Sie, dass Sie find -exec mit anderen Suchbefehlen wie -ls oder -delete oder ähnlichem folgen können . Beachten Sie, dass delete nicht nur rm (Dateien entfernt), sondern auch rmdir (Verzeichnisse entfernt).
Solch eine Kette wird als UND-Verknüpfung von Befehlen gelesen, sofern nichts anderes angegeben ist (nämlich mit einem -or
Schalter (und Parens (die maskiert werden müssen)).
Sie verlassen also nicht die Suchkette, was praktisch ist. Ich sehe keinen Vorteil in der Verwendung von -xargs, da Sie beim Übergeben der Dateien vorsichtig sein müssen, was bei find nicht erforderlich ist - es wird automatisch jede Datei als einzelnes Argument für Sie übergeben.
Wenn Sie glauben , Sie findet einige Maskierung benötigen {} Klammern , fühlen sich frei , meine Frage zu besuchen , die nach Beweisen fragt. Meine Behauptung ist: Du nicht.
find
. Vielen Dank!-exec
Art und Weise zu tun ,xargs -P4
so dass drei von vier Kernen nicht untätig bleiben?Das sichere Weiterleiten von Dateinamen an
xargs
erfordert, dass Siefind
die-print0
Option unterstützen undxargs
über die entsprechende Option zum Lesen verfügen (--null
oder-0
). Andernfalls können Dateinamen mit nicht druckbaren Zeichen oder umgekehrten Schrägstrichen oder Anführungszeichen oder Leerzeichen im Namen zu unerwartetem Verhalten führen. Andererseitsfind -exec {} +
ist es in der POSIX-find
Spezifikation enthalten , ist also portabel und ungefähr so sicher wiefind -print0 | xargs -0
und definitiv sicherer alsfind | xargs
. Ich würde empfehlen, niemalsfind | xargs
ohne auszukommen-print0
.quelle
find … -exec … {} +
OpenBSD ist OpenBSD, das diese Funktion erst mit der Version 5.1, die im Jahr 2012 veröffentlicht wurde, erworben hat-print0
. Solaris hingegen hält an POSIX-Funktionen fest, sodass Sie-exec +
keine Probleme haben-print0
.-print0
ist ein Schmerz und obwohl man argumentieren kann, dass erxargs --delimiter "\n"
nicht gleichwertig ist, habe ich den ersteren noch nie benutzt, nachdem ich den letzteren entdeckt habe.-0
schmerzhafter das ist--delimiter "\n"
.-0
GNUxargs
muss-r
Ausführen des Befehls vermeiden , wenn es keine Eingabe ist.| xargs -r0 cmd
ist, dasscmd
die stdin betroffen ist (je nachxargs
Implementierung ist es/dev/null
oder die Pipe.Wenn Sie das
-exec ... ;
Formular verwenden (daran denken, das Semikolon zu schließen), führen Sie den Befehl einmal pro Dateiname aus. Wenn Sie verwenden-print0 | xargs -0
, führen Sie mehrere Befehle pro Dateiname aus. Sie sollten auf jeden Fall das-exec +
Formular verwenden, das mehrere Dateien in einer einzigen Befehlszeile enthält und bei einer großen Anzahl von Dateien viel schneller ist.Ein großes Plus der Verwendung
xargs
ist die Möglichkeit, mehrere Befehle gleichzeitig auszuführenxargs -P
. Bei Multi-Core-Systemen kann dies eine enorme Zeitersparnis bedeuten.quelle
-P
statt-p
. Beachten Sie, dass diesxargs -P
nicht im POSIX-Standard enthalten ist. Diesfind -exec {} +
ist jedoch wichtig, wenn Sie Portabilität anstreben.find /tmp/ -exec ls "{}" +
.-exec
so lange vor allem davongekommen (ich bin ein Masochist, ich benutze nicht einmal Anführungszeichen{}
, ich tippe immer\{\}
; frage nicht), alles sieht so aus, als müsste es jetzt geflüchtet werden.find /tmp/ -exec ls {} +
es nicht funktionieren würde.bash
anfing, die Zahnspange wörtlich zu akzeptieren. Ich bin mir ziemlich sicher, dass mindestens eine der alten Muscheln, die ich verwendet habe, zischende Anfälle verursacht hat, wenn die Zahnspangen nicht entkommen sind.Was die Leistung angeht, dachte ich, das
-exec … +
wäre einfach besser, weil es ein einziges Tool ist, das die ganze Arbeit erledigt, aber ein Teil der Dokumentation von GNU findutil besagt, dass-exec … +
dies in einigen Fällen weniger effizient sein könnte:Ich war mir nicht ganz sicher, was das zu bedeuten hatte, also fragte ich im Chat, wo derobert es erklärte:
(Formatierung von mir.)
Das ist es also. Aber wenn es wirklich auf die Leistung ankommt, müsste man ein realistisches Benchmarking durchführen oder sich sogar fragen, ob man in solchen Fällen überhaupt die Shell verwenden möchte.
Hier auf dieser Seite ist es meines Erachtens besser, den Leuten zu raten, das
-exec … +
Formular zu verwenden, wann immer dies möglich ist, weil es einfacher ist und aus den in den anderen Antworten genannten Gründen (z. B. Umgang mit seltsamen Dateinamen, ohne viel nachzudenken).quelle