TLC :: Renommage massif de fichiers
La ligne de commande permet de faire énormément de choses. Nous allons voir comment renommer un nombre important de fichiers en une seule passe.
Admettons que vous venez d'importer toutes vos photos de vacances sur votre ordinateur. Vous avez un répertoire contenant toutes vos photos et celles-ci sont numérotées ainsi :
$ ls vegas.2008/ IMG_00001.jpg IMG_00013.jpg IMG_00025.jpg IMG_00037.jpg IMG_00049.jpg IMG_00002.jpg IMG_00014.jpg IMG_00026.jpg IMG_00038.jpg IMG_00050.jpg IMG_00003.jpg IMG_00015.jpg IMG_00027.jpg IMG_00039.jpg IMG_00051.jpg IMG_00004.jpg IMG_00016.jpg IMG_00028.jpg IMG_00040.jpg IMG_00052.jpg IMG_00005.jpg IMG_00017.jpg IMG_00029.jpg IMG_00041.jpg IMG_00053.jpg IMG_00006.jpg IMG_00018.jpg IMG_00030.jpg IMG_00042.jpg IMG_00054.jpg IMG_00007.jpg IMG_00019.jpg IMG_00031.jpg IMG_00043.jpg IMG_00055.jpg IMG_00008.jpg IMG_00020.jpg IMG_00032.jpg IMG_00044.jpg IMG_00056.jpg IMG_00009.jpg IMG_00021.jpg IMG_00033.jpg IMG_00045.jpg IMG_00057.jpg IMG_00010.jpg IMG_00022.jpg IMG_00034.jpg IMG_00046.jpg IMG_00058.jpg IMG_00011.jpg IMG_00023.jpg IMG_00035.jpg IMG_00047.jpg IMG_00059.jpg IMG_00012.jpg IMG_00024.jpg IMG_00036.jpg IMG_00048.jpg
Vous pouvez avoir envie de les renommer en vegas00001.jpg par exemple au lieu de IMG_00001.jpg.
Nous disposons de différents outils pour réaliser cela en une seule fois. Par exemple :
$ rename 's/.*(\d{5}).*/vegas$1.jpg/' *.jpg
rename est un script Perl permettant d'utiliser ses expressions relationnelles afin de renommer des fichiers. Il est présent par défaut dans Perl et donc devrait être disponible sur n'importe quelle distribution GNU/Linux. Pour les personnes ne connaissant pas les expressions rationnelles, je conseille la lecture de l'excellent livre de chez Oreilly : Mastering Regular Expressions.
On peut également utiliser une boucle for :
$ for pic in *jpg ; \
do mv $pic $(echo $pic | perl -ape 's/.*(\d{5}).*/vegas$1.jpg/'); done
Penchons-nous maintenant sur comment changer le suffixe des noms de fichiers. Nous avons un répertoire comportant des fichiers jpeg et nous voulons tous les renommer en jpg.
Avec Bash :
$ for i in *.jpeg;do mv $i $(basename $i .jpeg).jpg; done
Avec Zsh :
$ for i in *.jpeg; do mv $i ${i:r}.jpg; done
Le ${i:r} supprime le suffixe de la variable $i c'est-à-dire .jpeg par .jpg. Cela revient à faire l'équivalent d'un :
$ mv fichier.jpeg fichier.jpg
mais pour tous les fichiers en une seule fois :)
Je tiens à vous faire remarquer que la deuxième méthode est beaucoup plus rapide que celle utilisant basename.


Commentaires
#1 basename, parameter expansion
L'utilisation de basename est évidemment très coûteuse dans le one-liner bash ci-dessus.
Toutefois, l'expansion des paramètres n'est heureusement pas réservée à zsh, et la manière la plus portable d'exprimer le but voulu est l'utilisation de ${variable%mot} / {variable%%mot}.
On a donc, avec n'importe quel shell respectant POSIX :
$ for fichier in *.jpeg; do mv "$fichier" "${fichier%.jpeg}".jpg; doneUtilisable avec zsh, bash, dash, ksh, etc