xargs
erwartet ein ganz besonderes Eingabeformat, bei dem Argumente durch Leerzeichen oder Zeilenumbrüche begrenzt werden (manchmal andere Formen vertikaler Leerzeichen, manchmal abhängig vom aktuellen Gebietsschema) und bei denen einfache Anführungszeichen, doppelte Anführungszeichen und Backslash verwendet werden können, um sie zu umgehen (jedoch in einem anderen Weg von Shell-Anführungszeichen).
-l1
besteht nicht darin, eine Eingabezeile als ein einziges Argument an zu übergeben mkdir
, sondern einen mkdir
Aufruf für jede einzelne Eingabezeile aufzurufen , wobei jedoch Wörter in dieser Zeile immer noch als unterschiedliche Argumente getrennt sind mkdir
.
Die GNU-Implementierung hat vor Jahrzehnten xargs
eine -0
Option hinzugefügt , um NUL-begrenzte Eingaben zu akzeptieren. Dies ist der naheliegendste Weg, um Wörter zu trennen, die letztendlich Argumente für einen Befehl sein werden, da das NUL-Zeichen zufällig das einzige Zeichen ist, das in einem Befehlsargument oder Dateinamen nicht vorkommen kann (das von Ihnen gewählte Listenformat, in das eine Datei pro Zeile eingefügt wird kann nicht alle möglichen Dateinamen darstellen, da kein Zeilenumbruch in einem Dateinamen zulässig ist.
Das -0
wurde von mehreren anderen xargs
Implementierungen kopiert , aber nicht von allen.
Mit denen können Sie tun:
<file tr '\n' '\0' | xargs -0 mkdir -p --
Das wird mkdir
so wenig wie möglich mit so vielen Argumenten wie möglich aufgerufen .
Beachten Sie jedoch, dass wenn file
es leer ist, mkdir
es weiterhin ausgeführt wird und Sie mkdir
aufgrund des fehlenden Arguments einen Syntaxfehler erhalten . GNU xargs
hat eine -r
Option für die hinzugefügt , die von einigen anderen Implementierungen kopiert wurde.
GNU xargs
fügte (später) auch eine -d
Option hinzu , um beliebige Trennzeichen angeben zu können, aber ich glaube, keine andere Implementierung hat sie kopiert. Mit GNU xargs
ist der beste Weg mit:
xargs -rd '\n' -a file mkdir -p --
Wenn Sie die Datei mit -a
(auch einer GNU-Erweiterung) anstelle von stdin übergeben, mkdir
bleibt das stdin erhalten.
POSIXly müssten Sie die Eingabe nachbearbeiten, um sie in das von erwartete Format zu bringen xargs
. Sie könnten es zum Beispiel tun mit:
<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' | xargs mkdir -p --
Wo wir jede Zeile in doppelte Anführungszeichen setzen und jede "
wie "\""
vor dem Füttern an xargs maskieren.
Beachten Sie jedoch mögliche Einschränkungen:
- Der Fehler, wenn die Datei leer ist, wurde bereits oben erwähnt
- Bei einigen Implementierungen (einschließlich von
sed
) kann dies fehlschlagen, wenn der Inhalt von file
im aktuellen Gebietsschema kein gültiger Text ist. Wenn file
Dateinamen enthalten, die in mehr als einem anderen Zeichensatz oder einem anderen Zeichensatz als dem des Gebietsschemas codiert sind, können Sie das Gebietsschema auf C festlegen, was hilfreich sein sollte.
- Einige
xargs
Implementierungen haben lächerlich niedrige Grenzen für die maximale Länge eines Arguments (kann bis zu 255 Byte betragen).
Um den Syntaxfehler bei einem leeren Eingabefehler zu umgehen, können Sie Folgendes schreiben:
<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' |
xargs sh -c '[ "$#" -eq 0 ] || exec mkdir -p -- "$@"' sh
-d
Option.