IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Renommer tous les fichiers d'un répertoire à partir d'une liste


Sujet :

Shell et commandes GNU

  1. #1
    Membre du Club
    Femme Profil pro
    Inscrit en
    Août 2011
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 32
    Points : 50
    Points
    50
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 595
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 595
    Points : 19 477
    Points
    19 477
    Par défaut
    Bonjour,

    en bash, en utilisant un tableau :
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  3. #3
    Membre du Club
    Femme Profil pro
    Inscrit en
    Août 2011
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 32
    Points : 50
    Points
    50
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 ?

  4. #4
    Membre habitué
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 44
    Points : 146
    Points
    146
    Par défaut
    Bonjour,
    Quelle version de bash as-tu ?

    Je crains qu'elle ne supporte pas cette solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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<&-

  5. #5
    Membre du Club
    Femme Profil pro
    Inscrit en
    Août 2011
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 32
    Points : 50
    Points
    50
    Par défaut
    Super ça marche merci chardclo! Allez je vote pour toi +1 et pour N_BaH aussi

    -------------------------------------------------------------------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    i=1; while read line;do tabl[$i]=$line; i=$(($i+1));done < Fichier
    Ensuite je bloque à cette étape:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    sed --version | head -1 | awk  '{print $4}'
    4.1.2

  6. #6
    Membre habitué
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 44
    Points : 146
    Points
    146
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    echo ${BASH_VERSION[@]}

  7. #7
    Membre habitué
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 44
    Points : 146
    Points
    146
    Par défaut
    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

  8. #8
    Membre du Club
    Femme Profil pro
    Inscrit en
    Août 2011
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 32
    Points : 50
    Points
    50
    Par défaut
    Au passage...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 16/09/2009, 09h34
  2. Réponses: 1
    Dernier message: 12/09/2007, 11h42
  3. renommer tous les fichiers d'un répertoire
    Par khasanouray dans le forum Langage
    Réponses: 14
    Dernier message: 19/07/2007, 17h44
  4. Traiter tous les fichiers d'un répertoir sans les MFC.
    Par radicalrider dans le forum MFC
    Réponses: 12
    Dernier message: 21/06/2006, 17h18
  5. Réponses: 4
    Dernier message: 24/09/2004, 10h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo