Je travaille dans mon terminal en utilisant bash essayant de renommer les dossiers:
1
2
3
4
5
J'aimerais les renommer en fonction d'un fichier.txt:
a 2
c 3
d 5
e 1
b 4
L'ordre dans le fichier .txt est complètement aléatoire. J'espère trouver un moyen de renommer le dossier pour qu'il devienne:
1 > e
2 > a
3 > c
4 > b
5 > d
Est-ce qu'il y a un moyen de faire ça?
Merci beaucoup!
En supposant que les noms dans la liste n'incluent pas d'espaces , à l'exception de entre les noms, le script ci-dessous renommera les dossiers d’un fichier texte de manière récursive . Il lira les lignes du fichier, les scindera en deux (nouveau nom, ancien nom), renommera les dossiers d’origine nommés par la seconde chaîne la ligne, dans la première chaîne de la ligne.
Comme cela a été mentionné récursivement , il le fera de bas en haut dans l’arborescence. Cela évite les problèmes dans le script, en essayant de renommer des dossiers dans des dossiers parents éventuellement déjà renommés.
#!/usr/bin/env python
import os
import shutil
# -- set the (absolute) path to the targeted folder below
dr = "/home/jacob/Bureaublad/testfolder"
# -- set the path to the textfiles below
ren = "/home/jacob/Bureaublad/testfolder/renfile.txt"
renlist = [cpl for cpl in [l.split() for l in open(ren).readlines()] if cpl]
currnames = [r[1] for r in renlist]
for root, dirs, files in os.walk(dr, topdown = False):
for dr in dirs:
try:
# look up the name, pass if not in the list
i = currnames.index(dr)
except ValueError:
pass
else:
newname = renlist[i][0]
shutil.move(root+"/"+dr, root+"/"+newname)
rename.py
lancez le par la commande (dans un terminal):
python /path/to/rename.py
Le scénario:
os.walk()
de python, il parcourt vos répertoires de manière récursive, de bas en haut.Vous pouvez utiliser xargs
avec mv
:
xargs -r -a /path/to/file.txt -L1 mv
(en supposant que vous êtes dans le répertoire où se trouvent les fichiers).
xargs
convertit les entrées en arguments d'une commande.
-a foo
pour lire l'entrée de foo
.-L1
pour utiliser exactement une ligne d'entrée par appel de commande.-r
pour éviter d'exécuter la commande si la ligne est videPar exemple, utilisez echo mv
au lieu de mv
pour afficher les commandes en cours d'exécution:
$ xargs -r -a foo.txt -L1 echo mv
mv a 2
mv c 3
mv d 5
mv e 1
mv b 4
Vous pouvez également utiliser l'option -p
pour confirmer xargs
avant d'exécuter la commande:
$ xargs -r -p -a foo.txt -L1 mv
mv a 2 ?...n
mv c 3 ?...n
mv d 5 ?...y
mv e 1 ?...mv: cannot stat ‘d’: No such file or directory
n
mv b 4 ?...
Le fichier a.txt
contient une entrée par ligne. Par conséquent, les noms répertoriés ne contiennent pas de caractère \n
(nouvelle ligne), n'est-ce pas?
Une ligne contient 2 noms séparés par un caractère espace, de sorte que les noms ne contiennent pas espace caractère, non? (ou une autre possibilité serait d’utiliser une longueur fixe pour les noms listés).
Essayez ceci si les noms ne contiennent ni \n
ni space
caractères:
awk '{printf("%s\0%s\0",$2,$1)}' a.txt | xargs -0 -L 2 mv
awk
est utilisé pour inverser l'ordre des noms dans les lignes lues dans le fichier a.txt
. \0
est utilisé pour séparer les noms lorsqu'ils sont imprimés sur une sortie standard.
xargs
lit l'entrée standard:
-0
: \0
sert de séparateur pour les éléments lus à partir de l'entrée standard.-L 2 mv
: mv
la commande est appelée avec 2 paramètres à la fois.Le test:
$ ls -al
total 40
drwxrwxr-x 7 stacko stacko 4096 May 31 11:25 .
drwxrwxr-x 21 stacko stacko 12288 May 31 11:23 ..
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 1
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 2
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 3
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 4
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 5
-rw-rw-r-- 1 stacko stacko 20 May 31 11:24 a.txt
$ cat a.txt
a 2
c 3
d 5
e 1
b 4
$ awk '{printf("%s\0%s\0",$2,$1)}' a.txt | xargs -0 -L 2 mv -v
'2' -> 'a'
'3' -> 'c'
'5' -> 'd'
'1' -> 'e'
'4' -> 'b'
$ ls -al
total 40
drwxrwxr-x 7 stacko stacko 4096 May 31 11:26 .
drwxrwxr-x 21 stacko stacko 12288 May 31 11:23 ..
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 a
-rw-rw-r-- 1 stacko stacko 20 May 31 11:24 a.txt
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 b
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 c
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 d
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 e
Dans le cas simple que vous montrez ci-dessus, où chaque ligne a deux "mots", le répertoire cible et le nouveau nom, et où ni l'une ni l'autre ne peut contenir aucun espace, vous pouvez simplement faire:
while read -r from to; do mv "$from" "$to"; done < file
Cela lira chaque ligne dans file
assignera la première chaîne (jusqu'au premier espace blanc) à $from
et le reste de la ligne à $to
, puis exécutera mv
sur chacun des leur.