Script Bash[3] – renommer plusieurs fichiers – rename a bunch of files
Encore un pense-bête, cette fois pour faire du renommage massif de fichier, avec notamment sed et les expressions régulières.
—
Once again a reminder, today how-to mass-rename files, with sed and regular expressions.
Of course there is a lot of software[en] with graphical interface, user-friendly, etc. But hey, where is the fun !? ;)
As I have already shown you, simple script for simple renaming is sufficient:
for i in *.html; do mv $i.bak; done
You may also want to use find but I won’t go into details with it here.
You can use basename (and dirname) to do little more complicated:
for i in *htm; do mv $i `basename $i htm`html; done
or, some useful bash operator:
for i in *htm; do mv $i ${i%%.htm}.html; done
Little reminder:
With ## (resp. #) you can delete the longest (resp. shortest) substring corresponding to the pattern:
$ Name=’Rep/toto.tar.gz’
$ echo ${Name##*.}
> gz
$ echo ${Name#*.}
> tar.gz
$ echo ${Name##*t}
> ar.gz
$ echo ${Name#*t}
> oto.tar.gzTo do the same things with the end of the string use % (or %%):
$ echo ${Name%.*}
> Rep/toto.tar
$ echo ${Name%%.*}
> Rep/toto
$ echo ${Name%%t*}
> Rep/
$ echo ${Name%t*}
> Rep/toto.
More difficult, with Perl regular expressions and rename:
rename "s/htm/html/" *htm
Option -n to see what files would have been renamed.
Finally, with sed and regular expressions: You have files like 01_tilte1_album1.mp3, 03_tilte5_album9.mp3, and you want to delete the numbers; Or files like title_01_blabla.srt, title_02_blabla.srt and you want to remove all the title and blabla ? Here we go:
ls | sed -rn "s/^[0-9]+_(.*)/mv '&' '\1'/ p" | sh
-n : quiet mode
-r : extended regular expressions
^[0-9]+_ : start with some digits, followed by an underscore
(.*) : what we will keep
mv ‘&’ ‘\1’ : what we will do : move the matching files (‘&’) to what we will keep (‘\1’)
p : print the command
|sh : execute the command
Thus with only ls | …. p” you will see what files are concerned.
$ for i in `seq 8 1 12`; do touch $i\_title$i\_name$i\_$i$i.htm; done
$ ls
> 10_title10_name10_1010.htm 11_title11_name11_1111.htm 12_title12_name12_1212.htm 8_title8_name8_88.htm
> 9_title9_name9_99.htm
$ ls | sed -rn “s/^[0-9]+_(.*)htm/mv ‘&’ ‘\1’html/ p”
>
mv ’10_title10_name10_1010.htm’ ‘title10_name10_1010.’html
mv ’11_title11_name11_1111.htm’ ‘title11_name11_1111.’html
mv ’12_title12_name12_1212.htm’ ‘title12_name12_1212.’html
mv ‘8_title8_name8_88.htm’ ‘title8_name8_88.’html
mv ‘9_title9_name9_99.htm’ ‘title9_name9_99.’html
$ ls | sed -rn “s/.*(title.*)_name.*_(.*)htm/mv ‘&’ ‘\1_\2’html/ p”
>
mv ’10_title10_name10_1010.htm’ ‘title10_1010.’html
mv ’11_title11_name11_1111.htm’ ‘title11_1111.’html
mv ’12_title12_name12_1212.htm’ ‘title12_1212.’html
mv ‘8_title8_name8_88.htm’ ‘title8_88.’html
mv ‘9_title9_name9_99.htm’ ‘title9_99.’html
$ ls | sed -rn “s/^([0-9]+)_.*/mv ‘&’ ‘\1.html’/ p”
>
mv ’10_title10_name10_1010.htm’ ’10.html’
mv ’11_title11_name11_1111.htm’ ’11.html’
mv ’12_title12_name12_1212.htm’ ’12.html’
mv ‘8_title8_name8_88.htm’ ‘8.html’
mv ‘9_title9_name9_99.htm’ ‘9.html’
You just have to find the good regular expression, and then add the ‘| sh’ to execute ;)
And if you want to substitute underscores for blanks in all the filenames in a directory with a real script in your mybin directory:
#! /bin/bash
# blank-rename.sh
#
# Substitutes underscores for blanks in all the filenames in a directory.
ONE=1 # For getting singular/plural right (see below).
number=0 # Keeps track of how many files actually renamed.
FOUND=0 # Successful return value.for filename in * #Traverse all files in directory.
do
echo “$filename” | grep -q ” ” # Check whether filename
if [ $? -eq $FOUND ] #+ contains space(s).
then
fname=$filename # Yes, this filename needs work.
n=`echo $fname | sed -e “s/ /_/g”` # Substitute underscore for blank.
mv “$fname” “$n” # Do the actual renaming.
let “number += 1”
fi
doneif [ “$number” -eq “$ONE” ] # For correct grammar.
then
echo “$number file renamed.”
else
echo “$number files renamed.”
fi
exit 0
Source : advanced bash script guide[en], ShQWiki[en], the teaching of Emmanuel Viennet[fr], some fora, …
And please, do backups
—
Évidemment, il y a tout un tas de programmes[en] avec des interfaces utilisateurs, c’est joli et tout mais, où est le plaisir !? ;)
Comme je vous l’ai déjà montré, un script tout bête suffit à un renommage tout bête :
for i in *.html; do mv $i.bak; done
On peut utiliser basename (and dirname) pour faire un peu plus dur :
for i in *htm; do mv $i `basename $i htm`html; done
ou utiliser un opérateur bash :
for i in *htm; do mv $i ${i%%.htm}.html; done
Petit rappel :
Avec ## (resp. #) on peut supprimer la plus longue (resp. courte) chaine correspondant au motif :
$ Nom=’Rep/toto.tar.gz’
$ echo ${Nom##*.}
> gz
$ echo ${Nom#*.}
> tar.gz
$ echo ${Nom##*t}
> ar.gz
$ echo ${Nom#*t}
> oto.tar.gzPour faire la même chose avec la fin de la chaine, utilisez % (ou %%) :
$ echo ${Nom%.*}
> Rep/toto.tar
$ echo ${Nom%%.*}
> Rep/toto
$ echo ${Nom%%t*}
> Rep/
$ echo ${Nom%t*}
> Rep/toto.
Plus difficile, avec les expressions régulières de Perl et rename:
rename "s/htm/html/" *htm
Option -n pour voir les fichiers qui devraient être renommés.
Finallement, avec sed et les expressions régulières : vous avez des fichiers de la forme 01_tilte1_album1.mp3, 03_tilte5_album9.mp3, et vous voulez enlever les nombres ? ou des fichiers comme title_01_blabla.srt, title_02_blabla.srt et vous voulez virerle titre et le blabla ? C’est parti :
ls | sed -rn "s/^[0-9]+_(.*)/mv '&' '\1'/ p" | sh
-n : mode silencieux
-r : expressions régulières étendues
^[0-9]+_ : commence par des chiffres, suivis par un tiret bas
(.*) : ce qu’on va garder
mv ‘&’ ‘\1’ : ce qu’on va faire : déplacer le fichier correspondant au motif (‘&’) vers ce que l’on veut garder (‘\1’)
p : affiche la commande
|sh : exécute la commande
Donc avec seulement ls | …. p” vous verrez les fichiers concernés
$ for i in `seq 8 1 12`; do touch $i\_title$i\_name$i\_$i$i.htm; done
$ ls
> 10_title10_name10_1010.htm 11_title11_name11_1111.htm 12_title12_name12_1212.htm 8_title8_name8_88.htm
> 9_title9_name9_99.htm
$ ls | sed -rn “s/^[0-9]+_(.*)htm/mv ‘&’ ‘\1’html/ p”
>
mv ’10_title10_name10_1010.htm’ ‘title10_name10_1010.’html
mv ’11_title11_name11_1111.htm’ ‘title11_name11_1111.’html
mv ’12_title12_name12_1212.htm’ ‘title12_name12_1212.’html
mv ‘8_title8_name8_88.htm’ ‘title8_name8_88.’html
mv ‘9_title9_name9_99.htm’ ‘title9_name9_99.’html
$ ls | sed -rn “s/.*(title.*)_name.*_(.*)htm/mv ‘&’ ‘\1_\2’html/ p”
>
mv ’10_title10_name10_1010.htm’ ‘title10_1010.’html
mv ’11_title11_name11_1111.htm’ ‘title11_1111.’html
mv ’12_title12_name12_1212.htm’ ‘title12_1212.’html
mv ‘8_title8_name8_88.htm’ ‘title8_88.’html
mv ‘9_title9_name9_99.htm’ ‘title9_99.’html
$ ls | sed -rn “s/^([0-9]+)_.*/mv ‘&’ ‘\1.html’/ p”
>
mv ’10_title10_name10_1010.htm’ ’10.html’
mv ’11_title11_name11_1111.htm’ ’11.html’
mv ’12_title12_name12_1212.htm’ ’12.html’
mv ‘8_title8_name8_88.htm’ ‘8.html’
mv ‘9_title9_name9_99.htm’ ‘9.html’
Vous avez juste à trouver les bonnes expressions régulières, et à ajouter le ‘| sh’ pour exécuter ;)
Et si vous voulez changer les blancs dans les noms de fichiers par des tirets bas avec un script que vous aurez mis dans votre dossier monbin:
#! /bin/bash
# blank-rename.sh
#
# Substitue les tirets soulignés par des blancs dans tous les fichiers d'un
# répertoire.
UN=1 # Pour obtenir le singulier/pluriel correctement (voir
# plus bas).
nombre=0 # Garde trace du nombre de fichiers renommés.
TROUVE=0 # Valeur de retour en cas de succès.for fichier in * #Traverse tous les fichiers du répertoire.
do
echo “$fichier” | grep -q ” ” # Vérifie si le nom du fichier
if [ $? -eq $TROUVE ] #+ contient un (des) espace(s).
then
nomf=$fichier # Supprime le chemin.
n=`echo $nomf | sed -e “s/ /_/g”` # Remplace l’espace par un tiret.
mv “$nomf” “$n” # Réalise le renommage.
let “nombre += 1”
fi
done
if [ “$nombre” -eq “$UN” ] # Pour une bonne grammaire.
then
echo “$nombre fichier renommé.”
else
echo “$nombre fichiers renommés.”
fi
source : advanced bash script guide[fr], ShQWiki[en], le cours d’Emmanuel Viennet[fr], des fora, …
Et n’oubliez pas, faites des sauvegardes ;)
merci, la partie sur le renomage de fichiers en sed m’a permis de résoudre un problème correctement et rapidement :thumbsup:
pixx said this on 2015, January 28 - Wednesday at 12:16