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 :

[Débutant][script sh] Renommage de fichiers en masse


Sujet :

Shell et commandes GNU

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 101
    Points : 132
    Points
    132
    Par défaut [Débutant][script sh] Renommage de fichiers en masse
    Bonsoir à tous,

    Disposant d'un NAS, je souhaiterais pouvoir renommer les fichiers en masse tout en remplaçant certains caractères ennuyeux.
    à cet effet, j'ai cru bon de tenter de la faire via un script .sh
    je pense que ma syntaxe n'est pas correcte et est donc la cause de mon échec.
    je viens donc à vous quérir un peu d'aide.

    Le NAS ne dispose pas des commandes suivantes : Rename , Regex, Convmv. (beaucoups de posts invitant à l'utilisation de rename ne m'aident donc pas).

    Il dispose par contre des commandes suivantes : Find, Sed, Awk.

    je souhaiterais pouvoir remplacer les caractères suivants des noms de fichiers dans le répertoire courant, voir même ses sous-répertoires par le caractère "_"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    àâçéèêëîïôöûùü ÂÀÇÉÈÊËÎÏÔÖÙÛÜ ( ) [ ] ! ? +
    des caractères assez bizares qui correspondent respèctivement à "c" et "e"

    et si ces trois caractères sont présents ensembles les remplacer aussi par un simple _
    ainsi que le caractère d'espacement aussi par _

    pour ce faire j'ai tenté cette approche, sans succès:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find  . -type f -print0 | xargs -0 sed -r 's/^\.\/(.+)\.(.+)\!\'/\_-_\[]/\‡//àâçéèêëîïôöûùü/ÂÀÇÉÈÊËÎÏÔÖÙÛÜ/mv & .\/\2_\1.\2/\_/\_/\_/\_/c/e/aaceeeeiioouuu/AACEEEEIIOOUUU/'
    Comment puis-je faire aussi pour qu'il sois actif aussi bien dans le répertoire courant que dans ses sous-répertoire et sur tous les fichiers qui y sont présents ?

    d'avance merçi pour vos explications et suggestions.

    Cordialement
    Windows 7 / Debian 8 jessie / Kali 2 / Nas Synology ds214se / Arduino Mega 2560 / Raspberry Pi 3

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par hepha1970 Voir le message
    je souhaiterais pouvoir remplacer les caractères suivants des noms de fichiers dans le répertoire courant, voir même ses sous-répertoires par le caractère "_"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    àâçéèêëîïôöûùü ÂÀÇÉÈÊËÎÏÔÖÙÛÜ ( ) [ ] ! ? +
    des caractères assez bizares qui correspondent respèctivement à "c" et "e"

    et si ces trois caractères sont présents ensembles les remplacer aussi par un simple _
    ainsi que le caractère d'espacement aussi par _
    Hum... Y a plusieurs choses qui ne vont probablement pas bien marcher...

    Mais commençons par ce qui va marcher!

    Citation Envoyé par hepha1970 Voir le message
    Comment puis-je faire aussi pour qu'il sois actif aussi bien dans le répertoire courant que dans ses sous-répertoire et sur tous les fichiers qui y sont présents ?
    La commande "find" travaille sur tous les sous-répertoires et fichiers, donc c'est un bon point de départ!

    Citation Envoyé par hepha1970 Voir le message
    pour ce faire j'ai tenté cette approche, sans succès:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find  . -type f -print0 | xargs -0 sed -r 's/^\.\/(.+)\.(.+)\!\'/\_-_\[]/\‡//àâçéèêëîïôöûùü/ÂÀÇÉÈÊËÎÏÔÖÙÛÜ/mv & .\/\2_\1.\2/\_/\_/\_/\_/c/e/aaceeeeiioouuu/AACEEEEIIOOUUU/'
    J'ai l'impression que tu aimerais que cette commande "fasse" des choses comme "mv déjà.txt d_j_.txt", par exemple.

    Or, si la commande "sed" marchait, elle sortirait sur la stdout une telle chaine "mv déjà.txt d_j_.txt", c'est-à-dire qu'elle l'afficherait dans le terminal, mais elle ne l'exécuterait pas. Pour ça, il faudrait utiliser "eval", mais "eval is evil"...

    De plus, il y a beaucoup d'erreurs dans la commande "sed" qui ne s'utilise pas de la manière que tu emploies.

    Je te propose d'abandonner cette voie et de créer un script "fix_name.sh" qui fasse le renommage d'un seul fichier, de le tester à la main sur plusieurs cas, puis de le passer à "find" de la manière suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find  . -type f -exec fix_name.sh "{}" \;
    Dans un premier temps, il vaut mieux afficher la commande plutôt que l'exécuter, d'où la présence de "echo" qu'on retirera quand le script sera au point. Voici une base de départ:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    fix_name.sh
    #!/bin/sh
     
    if test $# -ne 1; then
        echo "usage: $0 <file>"
    fi 1>&2
     
    file1=$1
     
    # Traitement des caractères interdits
    file2=$(echo "${file1}" | sed -e 's/[ àâçéèêëîïôöûùü]/_/g' -e 's/[ÂÀÇÉÈÊËÎÏÔÖÙÛÜ]/_/g')
     
    # Traitement des caractères autorisés
    file3=$(echo "${file2}" | sed -e 's/[a-zA-Z_.\/]//g')
     
    # Traitement des caractères non traités
    if test ${#file3} -ne 0; then
        echo "Il reste ${#file3} caractères non traités '${file3}' dans '${file1}'"
        echo "don't" mv "${file1}" "${file2}"
        exit 1
    fi 2>&1
     
    if test "${file1}" = "${file1}"; then
        echo "don't rename ${file1}"
        exit 0
    fi
     
    echo mv "${file1}" "${file2}"
    Plusieurs remarques:
    Que doit-on faire si un répertoire contient des caractères spéciaux?
    Attention au codage (utf-8 iso-8859-1 etc.) du script.
    Il reste des caractères à traiter: laissé en exercice à l'utilisateur...

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 101
    Points : 132
    Points
    132
    Par défaut
    Bonsoir,

    Tout d'abord un grand merçi de m'avoir consacré un peu de ton temps.
    Vu que mon approche n'étais pas correcte, j'ai suivit votre proposition.
    j'ai donc crée un fichier du nom de fix_name.sh et y ai indiqué le script proposé.
    j'ai ensuite lancé la commande comme indiquée.

    en retour j'ai ceci à répetition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find: «fix_name.sh»: Aucun fichier ou dossier de ce type
    hors c'est incompréhensible vu que lorsque je fais un il me retourne bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    xxxx@xxxx-xx:~/Téléchargements/PDF$ ls *.sh 
    fix_name.sh
    xxxx@xxxx-xx:~/Téléchargements/PDF$

    le script à pourtant bien les permissions dont il à besoin

    Cordialement
    Windows 7 / Debian 8 jessie / Kali 2 / Nas Synology ds214se / Arduino Mega 2560 / Raspberry Pi 3

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par hepha1970 Voir le message
    Tout d'abord un grand merçi de m'avoir consacré un peu de ton temps.
    Vu que mon approche n'étais pas correcte, j'ai suivit votre proposition.
    j'ai donc crée un fichier du nom de fix_name.sh et y ai indiqué le script proposé.
    j'ai ensuite lancé la commande comme indiquée.

    en retour j'ai ceci à répetition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find: «fix_name.sh»: Aucun fichier ou dossier de ce type
    hors c'est incompréhensible vu que lorsque je fais un ls *.sh il me retourne bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    xxxx@xxxx-xx:~/Téléchargements/PDF$ ls *.sh 
    fix_name.sh
    xxxx@xxxx-xx:~/Téléchargements/PDF$
    le script à pourtant bien les permissions dont il à besoin
    C'est un symptome shell classique. Pour que le shell trouve une commande, il faut que celle-ci soit dans l'un des chemins contenus dans la variable $PATH. Or, il est fort probable que celle-ci ne contienne pas le répertoire dans lequel se trouve le script.

    Donc, plusieurs possibilités:
    ma préférée (pour un usage uniquement dans ce répertoire), ajouter le répertoire courant devant le nom de la commande:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find  . -type f -exec ./fix_name.sh "{}" \;
    Ajouter le répertoire absolu (pour un usage depuis d'autres répertoires):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    find  . -type f -exec /chemin/vers/le/script/fix_name.sh "{}" \;
    # Dans ton cas, ça donnerait:
    find  . -type f -exec ~/Téléchargements/PDF/fix_name.sh "{}" \;
    Déplacer le script dans un répertoire contenu dans $PATH:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    echo $PATH | tr ':' '\n' # une seule fois pour voir la liste des répertoires potentiels
    mv fix_name.sh /l/un/des/repertoires/ # une seule fois
    find  . -type f -exec fix_name.sh "{}" \; # maintenant, ça marche
    À titre indicatif, mon $PATH contient ~/SHELL où je mets tous les scripts dont je peux avoir régulièrement besoin.

    Ajouter le répertoire courant dans $PATH. Je n'aime pas trop cette solution car ~/Téléchargements/PDF n'est pas un répertoire destiné à accueillir des commandes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    PATH=${PATH}:~/Téléchargements/PDF # une seule fois
    find  . -type f -exec fix_name.sh "{}" \; # maintenant, ça marche
    Ajouter la valeur du répertoire courant dans $PATH. Je n'aime pas trop cette solution car elle conduit à des scripts non portables qui demandent à leurs utilisateurs externes de faire la même modification de leur $PATH:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    PATH=${PATH}:. # une seule fois
    find  . -type f -exec fix_name.sh "{}" \; # maintenant, ça marche

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    je ne crois pas que ce soit une bonne recommandation d'indiquer un chemin relatif (ici, le répertoire courant) dans le PATH. :/
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  6. #6
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    je ne crois pas que ce soit une bonne recommandation d'indiquer un chemin relatif (ici, le répertoire courant) dans le PATH. :/
    Tout à fait d'accord! C'est pour cela que j'ai bien indiqué que je n'aimais pas cette possibilité (ce n'est pas une recommandation!).

    Il se trouve que j'ai remarqué que certaines personnes le faisaient et qu'ils étaient surpris que leurs scripts ne marchassent pas dans un environnement différent du leur...

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    je ne comprends pas pourquoi l'indiquer comme possible.
    à la rigueur, l'indiquer comme étant à ne surtout pas faire, car ça crée une faille de sécurité.

    en effet, un "attaquant" pourrait déposer ses scripts n'importe où, et les exécuter.
    si j'ai bien compris.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 101
    Points : 132
    Points
    132
    Par défaut
    Bonjour,

    Je vous remerçies pour toutes ces précisions ainsi que pour le temps que vous m'avez consacré.
    Je note donc le sujet comme étant résolu.
    Encore merçi

    Cordialement
    Windows 7 / Debian 8 jessie / Kali 2 / Nas Synology ds214se / Arduino Mega 2560 / Raspberry Pi 3

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

Discussions similaires

  1. Script de renommage de fichiers dans un dossier donné
    Par johnbobby dans le forum VBScript
    Réponses: 2
    Dernier message: 24/07/2012, 16h23
  2. Renommage de fichiers en masse
    Par micbnd dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 22/07/2012, 21h01
  3. Réponses: 4
    Dernier message: 29/06/2009, 12h02
  4. Recherche d'un script PHP pour renommer des fichiers en masse
    Par pekka77 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 3
    Dernier message: 19/11/2006, 23h43
  5. Script de renommage auto fichier d'un repertoire
    Par faventin dans le forum Windows
    Réponses: 1
    Dernier message: 09/11/2006, 21h27

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