Wie kann ich xargs veranlassen, den Befehl für jede angegebene Eingabezeile genau einmal auszuführen? Standardmäßig werden die Zeilen aufgeteilt und der Befehl einmal ausgeführt, wobei jeder Zeile mehrere Zeilen übergeben werden.
Von http://en.wikipedia.org/wiki/Xargs :
find / path -type f -print0 | xargs -0 rm
In diesem Beispiel speist find die Eingabe von xargs mit einer langen Liste von Dateinamen. xargs teilt diese Liste dann in Unterlisten auf und ruft rm für jede Unterliste einmal auf. Dies ist effizienter als diese funktional äquivalente Version:
find / path -type f -exec rm '{}' \;
Ich weiß, dass find das Flag "exec" hat. Ich zitiere nur ein anschauliches Beispiel aus einer anderen Ressource.
find /path -type f -delete
wäre noch effizienter :)Antworten:
Folgendes funktioniert nur, wenn Ihre Eingabe keine Leerzeichen enthält:
von der Manpage:
quelle
xargs -n 1
die von Ihnen angegebene "Argumentliste zu lang" gezeigt.MAX-LINES
weggelassen wird, wird standardmäßig 1 verwendet,xargs -l
was ausreicht. Sieheinfo xargs
.echo "foo bar" | xargs -n1 echo
. Wenn Sie also Dinge wie 'ls' einpfeifen, werden Leerzeichen nicht gut verarbeitet.-L 1
beantwortet die ursprüngliche Frage nicht und-n 1
dies nur in einer der möglichen Interpretationen. Siehe meine lange Antwort unten.-L 1
macht es. Für mich schien das OP eindeutig zu versuchen, das Standard-Chunking-Verhalten zu vermeiden, und da dies akzeptiert wurde, gehe ich davon aus, dass ich Recht hatte. Ihre Antwort befasst sich mit einem etwas anderen Anwendungsfall, in dem Sie auch das Chunking-Verhalten wünschen.Mir scheint, dass alle auf dieser Seite vorhandenen Antworten falsch sind, einschließlich der als richtig gekennzeichneten. Das liegt daran, dass die Frage nicht eindeutig formuliert ist.
Zusammenfassung: Wenn Sie den Befehl "genau einmal für jede angegebene Eingabezeile" ausführen möchten und die gesamte Zeile (ohne die neue Zeile) als einzelnes Argument an den Befehl übergeben möchten , ist dies die beste UNIX-kompatible Methode:
GNU verfügt
xargs
möglicherweise über nützliche Erweiterungen, mittr
denen Sie diese beseitigen können. Sie sind jedoch unter OS X und anderen UNIX-Systemen nicht verfügbar.Nun zur langen Erklärung…
Bei der Verwendung von xargs sind zwei Punkte zu berücksichtigen:
Um das Verhalten von xargs zu testen, benötigen wir ein Dienstprogramm, das anzeigt, wie oft es ausgeführt wird und mit wie vielen Argumenten. Ich weiß nicht, ob es dafür ein Standarddienstprogramm gibt, aber wir können es ganz einfach in bash codieren:
Angenommen, Sie speichern es
show
in Ihrem aktuellen Verzeichnis und machen es ausführbar. So funktioniert es:Wenn es sich bei der ursprünglichen Frage wirklich um Punkt 2 oben handelt (wie ich denke, nachdem ich sie einige Male gelesen habe) und sie so zu lesen ist (Änderungen in Fettdruck):
dann ist die Antwort
-n 1
.Vergleichen wir das Standardverhalten von xargs, bei dem die Eingabe um Leerzeichen aufgeteilt wird und der Befehl so oft wie möglich aufgerufen wird:
und sein Verhalten mit
-n 1
:Wenn sich die ursprüngliche Frage andererseits auf Punkt 1 bezog und die Aufteilung der Eingaben so war (viele Leute, die hierher kommen, scheinen zu glauben, dass dies der Fall ist, oder verwechseln die beiden Probleme):
dann ist die Antwort subtiler.
Man würde denken, dass
-L 1
dies hilfreich sein könnte, aber es stellt sich heraus, dass es das Parsen von Argumenten nicht ändert. Der Befehl wird für jede Eingabezeile nur einmal ausgeführt, mit so vielen Argumenten, wie in dieser Eingabezeile vorhanden waren:Nicht nur das, sondern wenn eine Zeile mit Leerzeichen endet, wird sie an die nächste angehängt:
Es geht natürlich
-L
nicht darum, die Art und Weise zu ändern, in der xargs die Eingabe in Argumente aufteilt.Das einzige Argument, das dies plattformübergreifend tut (ausgenommen GNU-Erweiterungen), ist
-0
die Aufteilung der Eingabe auf NUL-Bytes.Dann geht es nur noch darum, Zeilenumbrüche mit Hilfe von
tr
: in NUL zu übersetzen :Jetzt sieht die Argumentanalyse gut aus, einschließlich des nachgestellten Leerzeichens.
Wenn Sie diese Technik mit kombinieren
-n 1
, erhalten Sie genau eine Befehlsausführung pro Eingabezeile, unabhängig von Ihrer Eingabe. Dies kann eine weitere Möglichkeit sein, die ursprüngliche Frage zu betrachten (möglicherweise die intuitivste, wenn man den Titel bedenkt):quelle
-L
führt den Befehl einmal pro Eingabezeile aus (ein Leerzeichen am Ende einer Zeile verbindet ihn jedoch mit der nächsten Zeile, und die Zeile wird weiterhin nach Leerzeichen in Argumente aufgeteilt). while-n
führt den Befehl einmal pro Eingabeargument aus. Wenn Sie die Anzahl->
in den Ausgabebeispielen zählen, ist dies die Häufigkeit, mit der das Skript./show
ausgeführt wird.xargs
kann nützliche Erweiterungen haben oder nicht, die es Ihnen ermöglichen, es zu beseitigen.tr
Es hat eine so sehr nützliche Erweiterung; fromxargs --help
- -d, --delimiter = CHARACTER-Elemente im Eingabestream werden durch CHARACTER und nicht durch Leerzeichen getrennt. deaktiviert die Quotierungs- und Backslash-Verarbeitung und die logische EOF-Verarbeitung-L
.-L
Gibt nicht an, wie oft das Skript pro Zeile ausgeführt werden soll, sondern wie viele Zeilen mit Eingabedaten gleichzeitig verbraucht werden sollen.Wenn Sie den Befehl für jede Zeile (dh das Ergebnis) ausführen möchten, von der Sie kommen
find
, wofür benötigen Sie dann den Befehlxargs
?Versuchen:
find
Pfad-type f -exec
dein-Befehl{} \;
Dabei wird das Literal
{}
durch den Dateinamen ersetzt und das Literal\;
wird benötigt, umfind
zu wissen, dass der benutzerdefinierte Befehl dort endet.BEARBEITEN:
(nach der Bearbeitung Ihrer Frage klarstellen, dass Sie wissen
-exec
)Von
man xargs
:Beachten Sie, dass Dateinamen, die mit Leerzeichen enden, Probleme verursachen können, wenn Sie Folgendes verwenden
xargs
:Wenn Sie sich also nicht für die
-exec
Option interessieren , verwenden Sie besser-print0
und-0
:quelle
-L 1
ist die einfache Lösung, funktioniert aber nicht, wenn eine der Dateien Leerzeichen enthält. Dies ist eine Schlüsselfunktion des-print0
Arguments von find - um die Argumente durch '\ 0' anstelle von Leerzeichen zu trennen. Hier ist ein Beispiel:Eine bessere Lösung besteht darin
tr
, Zeilenumbrüche in null (\0
) Zeichen zu konvertieren und dann dasxargs -0
Argument zu verwenden. Hier ist ein Beispiel:Wenn Sie dann die Anzahl der Aufrufe begrenzen müssen, können Sie das
-n 1
Argument verwenden, um das Programm für jede Eingabe einmal aufzurufen:Auf diese Weise können Sie auch die Ausgabe von find filtern, bevor Sie die Unterbrechungen in Nullen konvertieren.
quelle
-L
besteht darin, dass nicht für jedenxargs
Befehlsaufruf mehrere Argumente zulässig sind."Eine andere Alternative ...
quelle
Diese beiden Methoden funktionieren auch für andere Befehle, die find nicht verwenden!
Anwendungsbeispiel:
löscht alle pyc-Dateien in diesem Verzeichnis, auch wenn die pyc-Dateien Leerzeichen enthalten.
quelle
ist alles, was du brauchst.
quelle
Der folgende Befehl findet alle Dateien (-typ f) in
/path
und kopiert sie dann mitcp
in den aktuellen Ordner. Beachten Sie die Verwendung von if-I %
, um ein Platzhalterzeichen in dercp
Befehlszeile anzugeben , damit Argumente nach dem Dateinamen platziert werden können.find /path -type f -print0 | xargs -0 -I % cp % .
Getestet mit Xargs (GNU findutils) 4.4.0
quelle
Sie können die Anzahl der Zeilen oder Argumente (wenn zwischen den einzelnen Argumenten Leerzeichen stehen) mit den Flags --max-lines bzw. --max-args begrenzen.
quelle
Es scheint, dass ich nicht genug Ruf habe, um Tobias Antwort oben einen Kommentar hinzuzufügen, also füge ich diese "Antwort" hinzu, um denjenigen von uns zu helfen, die
xargs
auf den Windows-Plattformen auf die gleiche Weise experimentieren möchten .Hier ist eine Windows-Batch-Datei, die dasselbe tut wie Tobias schnell codiertes "Show" -Skript:
quelle
@ Draemon-Antworten scheinen mit "-0" auch bei Platz in der Datei richtig zu sein.
Ich habe den Befehl xargs ausprobiert und festgestellt, dass "-0" perfekt mit "-L" funktioniert. Sogar die Leerzeichen werden behandelt (wenn die Eingabe mit Null abgeschlossen wurde). Das Folgende ist ein Beispiel:
Im Folgenden werden die Nullen aufgeteilt und der Befehl für jedes Argument in der Liste ausgeführt:
führt also
-L1
das Argument für jedes nullterminierte Zeichen aus, wenn es mit "-0" verwendet wird. Um den Unterschied zu sehen, versuchen Sie:Auch dies wird einmal ausgeführt:
Der Befehl wird einmal ausgeführt, da "-L" jetzt nicht auf Null-Byte aufgeteilt wird. Sie müssen sowohl "-0" als auch "-L" angeben, um zu arbeiten.
quelle
In Ihrem Beispiel besteht der Punkt beim Weiterleiten der Ausgabe von find an xargs darin, dass das Standardverhalten der Option -exec von find darin besteht, den Befehl für jede gefundene Datei einmal auszuführen. Wenn Sie find verwenden und das Standardverhalten wünschen, ist die Antwort einfach - verwenden Sie zunächst keine xargs.
quelle
find
, und deshalb bevorzugen sie die-exec
Option nicht.Führen Sie ant task clean-all für jede build.xml im aktuellen Ordner oder Unterordner aus.
quelle
ant
installiert.