J'en ai un file
qui contient une liste de noms. c'est à dire:
Long Name One (001)
Long Name Two (201)
Long Name Three (123)
...
avec des espaces et quelques caractères spéciaux. Je voulais créer des répertoires à partir de ces noms, c'est-à-dire:
cat file | xargs -l1 mkdir
Il fait des répertoires individuels séparés par des espaces, par exemple Long
, Name
, One
, Two
, Three
, au lieu de Long Name One (001)
, Long Name Two (201)
, Long Name Three (123)
.
Comment puis je faire ça?
shell
xargs
whitespace
Majal
la source
la source
-d
option.Si votre
-0
option de support d'implémentation xargs :POSIX:
(Notez que l'utilisation de la
while
boucle pour traiter le texte est considérée comme une mauvaise pratique dans le script shell)la source
mkdir
par répertoire,mkdir
peut prendre plus d'un argument.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 unemkdir
invocation pour chaque ligne d'entrée mais avec des mots sur cette ligne toujours séparés en tant qu'arguments différentsmkdir
.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 autresxargs
implémentations mais pas toutes.Avec ceux que vous pouvez faire:
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 enmkdir
raison de l'argument manquant. GNU axargs
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 GNUxargs
, le meilleur moyen est de:En passant le fichier avec
-a
(également une extension GNU) au lieu de stdin, cela signifie quemkdir
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:Où nous enfermons chaque ligne entre guillemets doubles et s'échappons
"
comme"\""
avant d'alimenter xargs.Mais attention aux limitations possibles:
sed
) si le contenu defile
n'est pas du texte valide dans les paramètres régionaux actuels. Sifile
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.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:
la source
Rendez les noms nuls et séparez-les:
tr
remplacera le retour à la ligne qui sortcat
avec\0
, et les-0
drapeauxxargs
dedans lui disent de diviser les arguments sur le\0
.la source
Vous pouvez le faire POSIXLEMENT avec l'
-I
option:http://pubs.opengroup.org/onlinepubs/9699919799/utilities/xargs.html
la source