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; done
Utilisable avec zsh, bash, dash, ksh, etc