J'ai un fichier .txt qui contient un texte comme celui-ci
A1/B1/C1
A2/B2/C2
A3/B3/C3
Je veux un script qui lit le fichier .txt pour chaque ligne puis crée un répertoire basé sur le premier mot (A1, A2, A3)
J'ai créé un script comme celui-ci:
file="test.txt"
while IFS='' read -r line
do
name="line"
mkdir -p $line
done <"$file"
Pendant que je l'exécute, il crée le répertoire A1 puis crée également les sous-répertoires B1 et C1. il en va de même pour une autre ligne (A2 * et A3 *)
Que dois-je faire pour créer uniquement des répertoires A1, A2, A3?
Je ne veux pas faire le nom comme A1 / B1 / C1 avec le caractère '/' dedans. Je veux juste prendre le mot avant le caractère '/' et lui donner le nom du répertoire. Juste "A1" "A2" "A3".
xargs -a<(....)
plutôt que<dirlist.txt cut -d/ -f1 | xargs
?tr
approche - je viens de réaliser queparallel
cela est couvert par défaut.xargs -a<(....)
plutôt qu'une pipe - parce que j'aime ça comme ça, aussi simple que ça. :)<(...)
aide également avec les espaces, donc c'est certainement le meilleur choix - je ne pense pas que quiconque utilisait ce descripteur de fichier de toute façon.cut <dirlist.txt
au lieu de justecut dirlist.txt
?Vous devez définir votre
IFS='/'
pourread
, puis affecter chaque premier champ en variable distinctefirst
et le reste des champs en variablerest
et simplement travailler sur la valeur du premier champ (ou vous pouvezread -ar array
utiliser un seul tableau et utiliser"${array[0]}"
pour la première valeur du champ.):Ou en une seule ligne pour ceux qui l'aiment:
Ou créez tous les répertoires en une seule fois:
La citation ANSI-C
$'...'
est utilisée pour traiter les noms de répertoire contenant des caractères spéciaux.Notez que le
_
(peut être n'importe quel caractère ou chaîne) à la fin sera argv [0] à labash -c '...'
et la$@
volonté contiendra le reste des paramètres à partir de 1; sans cela dans la seconde commande, le premier paramètre dumkdir
sera perdu.En
${1%%/*}
utilisant l' expansion de substitution de paramètres shell (POSIX sh / bash / Korn / zsh) , supprime la correspondance la plus longue possible d'une barre oblique suivie de tout jusqu'à la fin du paramètre qui y passe, qui est une ligne lue par xargs ;Ps:
echo
devant lemkdir
pour créer ces répertoires.-d'\n'
par-0
si votre liste est séparée par des caractères NUL au lieu d'une ligne\n
électronique (supposé qu'il y ait / soit une nouvelle ligne intégrée dans le nom de votre répertoire).la source
Contenu de
test.txt
:Script pour créer des
A[123]
dossiers:Sortie de
ls
:la source
A 12"x4" dir/B b/C c
:?Pour un cas simple, comme indiqué dans l'exemple d'entrée de la question, utilisez
cut
et transmettez simplement la sortie àmkdir
viaxargs
Pour gérer les cas où le nom du répertoire peut contenir des espaces, nous pourrions ajouter
-d '\n'
à la liste des options:Pour des variantes plus complexes, telles que
A 12"x4" dir/B b/C c
suggérées par @OleTange dans les commentaires, on peut se tourner versawk
pour créer une liste séparée par des valeurs nulles au lieu d'une liste séparée par des sauts de ligne.@dessert s'est demandé dans les commentaires s'il
printf
pouvait être utilisé à la place decut
, et techniquement parlant, il peut être utilisé, par exemple en limitant la chaîne imprimée à la largeur de 3 caractères seulement:Ce n'est pas la manière la plus propre, mais cela prouve
printf
qu'on peut l'utiliser. Bien sûr, cela devient problématique si le nom du répertoire dépasse 3 caractères.la source
A 12"x4" dir/B b/C c
:?en utilisant Perl:
Ou
si nous voulons accepter des espaces sur dir-names
la source
perl -ne 'mkdir for /^([^\/]+)/' list.txt
pour couvrir les espaces dans les noms dir. J'ai enfin besoin d'apprendre Perl - merci!GNU Parallel peut être exagéré pour la tâche, mais si vous allez faire d'autres choses pour chaque ligne, cela peut être utile:
Il traite correctement les entrées comme:
la source