xargs
attend un format d'entrée très spécial où les arguments sont délimités par des espaces ou des retours à la ligne (parfois d'autres formes d'espaces verticaux, parfois dépendants des paramètres régionaux actuels), et où des guillemets simples, des guillemets doubles et une barre oblique inversée peuvent être utilisés pour les échapper (mais dans un autre des citations shell).
-l1
ne consiste pas à passer une ligne d'entrée en tant qu'argument unique à mkdir
, mais à appeler une mkdir
invocation pour chaque ligne d'entrée mais avec des mots sur cette ligne toujours séparés en tant qu'arguments différents mkdir
.
L'implémentation GNU a xargs
ajouté une -0
option il y a des décennies pour accepter les entrées délimitées par NUL. C'est le moyen le plus évident de séparer les mots qui finiront par être des arguments d'une commande car le caractère NUL se trouve être le seul caractère qui ne peut pas apparaître dans un argument de commande ou un nom de fichier (le format de liste choisi qui place un fichier par ligne ne peut pas représenter tous les noms de fichiers possibles car il n'autorise pas la nouvelle ligne dans un nom de fichier).
Cela -0
a été copié par plusieurs autres xargs
implémentations mais pas toutes.
Avec ceux que vous pouvez faire:
<file tr '\n' '\0' | xargs -0 mkdir -p --
Cela appellera mkdir
le moins de fois possible avec autant d'arguments que possible.
Mais notez que si file
est vide, mkdir
sera toujours exécuté et vous obtiendrez une erreur de syntaxe en mkdir
raison de l'argument manquant. GNU a xargs
ajouté une -r
option pour celle qui a été copiée par quelques autres implémentations.
GNU a xargs
également ajouté (plus tard) une -d
option pour pouvoir spécifier des délimiteurs arbitraires, mais je pense qu'aucune autre implémentation ne l'a copiée. Avec GNU xargs
, le meilleur moyen est de:
xargs -rd '\n' -a file mkdir -p --
En passant le fichier avec -a
(également une extension GNU) au lieu de stdin, cela signifie que mkdir
le stdin est préservé.
POSIX, vous devez post-traiter l'entrée pour la mettre au format attendu par xargs
. Vous pouvez le faire par exemple avec:
<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' | xargs mkdir -p --
Où nous enfermons chaque ligne entre guillemets doubles et s'échappons "
comme "\""
avant d'alimenter xargs.
Mais attention aux limitations possibles:
- l'erreur lorsque le fichier est vide déjà mentionné ci-dessus
- il peut échouer avec certaines implémentations (y compris de
sed
) si le contenu de file
n'est pas du texte valide dans les paramètres régionaux actuels. Si file
contient des noms de fichier codant dans plusieurs jeux de caractères différents, ou un jeu de caractères différent de celui des paramètres régionaux, vous pouvez corriger les paramètres régionaux en C, ce qui devrait vous aider.
- certaines
xargs
implémentations ont des limites ridiculement basses sur la longueur maximale d'un argument (peut être aussi bas que 255 octets).
Pour contourner l' erreur de syntaxe en cas d'erreur d'entrée vide , vous pouvez écrire:
<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' |
xargs sh -c '[ "$#" -eq 0 ] || exec mkdir -p -- "$@"' sh
-d
option.