Précédent   Forum des professionnels en informatique > Systèmes > Linux > Applications > Shell
Shell Vos questions sur l'utilisation des commandes shell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 31/08/2011, 19h46   #1
Nouveau Membre du Club
 
Femme
Inscription : août 2011
Messages : 22
Détails du profil
Informations personnelles :
Sexe : Femme

Informations forums :
Inscription : août 2011
Messages : 22
Points : 29
Points : 29
Par défaut Renommer tous les fichiers d'un répertoire à partir d'une liste

Bonjour à tous,

Je suis sur que beaucoup d'entre vous vont rigoler tellement c'est simple à faire, pour ma part j'ai la solution à mon problème, seulement elle fait intervenir trop d'outils.

La problématique:

J'ai un répertoire /fichiers_à_renommer/ contenant 1000 fichiers dont les noms sont

Code :
1
2
3
4
5
ls /fichiers_à_renommer
IMG0001
IMG0002
IMG0003
...
J'ai dans un fichier LISTE, une liste de nom de fichier, 1000 au total.

Code :
1
2
3
4
5
cat LISTE
Ma_première_photo
Mon_ Pays
La_voisine
...
Je cherche à renommer les noms des fichiers contenu dans mon répertoire /fichiers_à_renommer/ avec ceux contenu dans mon fichier liste et de manière respective.

J'ai une solution avec la ligne de commande

Code :
for file in IMG0001; do mv $file ${file/*/Ma_première_photo} ;done
Puis avec excel je génère l'ensemble des commandes pour le renommage correspondant, le problème c'est assez long...

Je pense qu'en ligne de commande c'est possible mais je ne vois pas comment m'y prendre, je suis sur que c'est super facile, mais après avoir cherché sur le forum, je n'ai pas trouvé quelque choses de similaire.

Merci à ceux qui m'aideront.
erustika est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 31/08/2011, 20h30   #2
Expert Confirmé Sénior
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 071
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 071
Points : 4 154
Points : 4 154
Bonjour,

en bash, en utilisant un tableau :
Code bash :
1
2
3
4
5
rep=tonRepertoire
tabl=(); while read line; do tabl+=( "$line" ); done < Fichier
for fichier in $rep/IMG*
do mv "$fichier" "$rep/${tabl[n++]}"
done
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 01/09/2011, 10h26   #3
Nouveau Membre du Club
 
Femme
Inscription : août 2011
Messages : 22
Détails du profil
Informations personnelles :
Sexe : Femme

Informations forums :
Inscription : août 2011
Messages : 22
Points : 29
Points : 29
En effet, je n'ai pas pensé à utiliser un tableau, bien vue

Par contre, j'ai un autre souci lors de l'exécution:

Code :
1
2
tabl=(); while read line; do tabl+=( "$line" ); done < fichier
-bash: syntax error near unexpected token `"$line"'
L'affectation de variable ne fonctionne pas sur shell bash ?
erustika est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 01/09/2011, 12h05   #4
Membre actif
 
Homme
Inscription : août 2011
Messages : 44
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : août 2011
Messages : 44
Points : 153
Points : 153
Bonjour,
Quelle version de bash as-tu ?

Je crains qu'elle ne supporte pas cette solution :
Code :
1
2
3
4
5
6
exec 3< <(printf "%s\n" IMG*)
while read && read -u3 old
do
  mv "${old}" "${REPLY}"
done < fichier
exec 3<&-
Et si ce n'est pas le cas, essaie ceci :
Code :
1
2
3
4
printf "%s\n" IMG*|paste - fichier |while read old new
do
mv "${old}" "${new}"
done
A noter que fichier doit avoir une ligne vierge à la fin.

EDIT : reste à espérer que tes fichiers n'ont pas de blanc dans leur nom

EDIT2 :
Code :
1
2
3
4
5
6
exec 3<fichier
printf "%s\n" IMG*|while read && read -u3 new
do
  mv "${REPLY}" "${new}" 
done
exec 3<&-
chardclo est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 01/09/2011, 14h43   #5
Nouveau Membre du Club
 
Femme
Inscription : août 2011
Messages : 22
Détails du profil
Informations personnelles :
Sexe : Femme

Informations forums :
Inscription : août 2011
Messages : 22
Points : 29
Points : 29
Super ça marche merci chardclo! Allez je vote pour toi +1 et pour N_BaH aussi

-------------------------------------------------------------------------
Code :
1
2
3
4
5
6
exec 3< Fichier
printf "%s\n" IMG*|while read && read -u3 new
do
  mv "${REPLY}" "${new}" 
done
exec 3<&-
-------------------------------------------------------------------------
  • Première solution
Par contre pour revenir à la première solution, celle de N_BaH que j'aime bien aussi j'ai avancé entre temps dans mon problème, j'ai réussi à alimenter mon tableau de cette façon:

Code :
i=1; while read line;do tabl[$i]=$line; i=$(($i+1));done < Fichier
Ensuite je bloque à cette étape:

Code :
1
2
for fichier in $rep/IMG*; do mv "$fichier" "$rep/${tabl[n++]}"; done;
mv: `/rep/IMG0001' and `/rep/IMG0001' are the same file
Pourtant la première occurrence du tableau me renvoi bien la première entrée de mon fichier

Code :
1
2
echo ${tabl[1]}
Mon_premier_nom
J'ai donc la seconde proposition qui marche (celle de chardclo), cependant, j'aimerai bien réussir à faire marcher la première (celle de N_BaH) si c'est possible, car la notion de tableau est très intéressante et réutilisable.

La version de mon bash

Code :
1
2
sed --version | head -1 | awk  '{print $4}'
4.1.2
erustika est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/09/2011, 15h13   #6
Membre actif
 
Homme
Inscription : août 2011
Messages : 44
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : août 2011
Messages : 44
Points : 153
Points : 153
Salut,

Je ne comprends pas le comportement que tu obtiens. Ce n'est pas normal que tu aies un nom existant dans le tableau tabl

Pour contruire ton tableau, je te propose de procéder ainsi :
Code :
1
2
IFS=$'\n' tabl=( $(<fichier) )
unset IFS
Aussi, les indices de tableaux commencent à 0, il ne faut donc pas initialiser i à 1 (mais 0) si tu tiens à utiliser ton principe.

Par ailleurs, tabl[$i]=$line; i=$(($i+1)) peut se simplifier ainsi : tabl[i++]="$line" (comme l'a indiqué N_BaH)

EDIT : La version de bash s'obtient ainsi :
Code :
echo ${BASH_VERSION[@]}
chardclo est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 01/09/2011, 16h52   #7
Membre actif
 
Homme
Inscription : août 2011
Messages : 44
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : août 2011
Messages : 44
Points : 153
Points : 153
Re,

Bon, j'ai compris pourquoi tu as ce comportement !
C'est lié au premier indice de ton tableau qui est 1 et non 0.
En effet, au premier passage dans ta boucle de renommage, "n" n'est pas défini. Du coup ${tabl[n++]} retourne la valeur de ${tabl[0]} qui est vide.

Ainsi mv "$fichier" "$rep/${tabl[n++]}" équivaut à mv "$fichier" "$rep/${tabl[0]}", c.a.d mv "$fichier" "$rep/"En conséquence, tu renommes IMG0001 vers lui même !

Voilà pour l'explication
chardclo est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 01/09/2011, 17h10   #8
Nouveau Membre du Club
 
Femme
Inscription : août 2011
Messages : 22
Détails du profil
Informations personnelles :
Sexe : Femme

Informations forums :
Inscription : août 2011
Messages : 22
Points : 29
Points : 29
Au passage...

Code :
1
2
echo ${BASH_VERSION[@]}
3.00.15(1)-release
Tu es trop fort chardclo !!!

Merci beaucoup, ça fonctionne maintenant

Par contre pour l'alimentation de mon tableau je dois donc bien utiliser cette syntaxe:

Code :
while read line;do tabl[i++]="$line" ;done < Fichier
Et donc la suite fonctionne puisque la première occurrence du tableau n'est pas vide

Un grand merci à tous les deux
erustika est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 21h50.


 
 
 
 
Partenaires

Hébergement Web