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 :

Script pour renommer des fichiers


Sujet :

Shell et commandes GNU

  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 137
    Par défaut Script pour renommer des fichiers
    Bonjour à tous ,

    J'aimerai faire un script de renommage de fichier par lot pour mes séries. La particularité de récupérer dans un premiere temps de récupérer le numéro de la série et l'extension des fichier.

    Exemple
    mes fichiers se présentent sous la forme suivante [nomteam]nom de la série_numéro de la série(1280x720[F8F6F8A2].extension

    Donc j'ai regarder avec les divers commandes (awk, sed, renamme) mais j'ai du mal à trouver le bon moyen pour extraire ces informations.

    merci par avance pour l'aide

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    Bonjour,

    parce qu'on ne va pas faire tes devoirs :
    tu veux récupérer ce qui entre _ et ( et ce qui est après le ..

    cf. man 7 regex.
    de plus, ce sujet est couramment traité sur ce forum, fais quelques recherches.


    récupérer dans un premiere temps
    et ensuite ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 137
    Par défaut
    Ce script est pour un usage personnel et non un devoir



    tu veux récupérer ce qui entre _ et ( et ce qui est après le ..
    Oui et non je voudrai savoir si il est possible d'effacer les lettres et chiffre superflue en faite en une seule fois ?

    Une fois mes informations crée je fais une boucle pour lancer un traitement sur mes dossiers .

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    avec n'importe quelle commande gérant les regexes (grep pour des trucs simples, mais plutôt sed, rename), et la regex ad hoc.

    il faudrait plus d'exemples, et les résultats attendus.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 137
    Par défaut
    La structure du script serait de ce genre


    [nomteam]nom de la série_01(1280x720[F8F6F8A2].extension
    [nomteam]nom de la série_02(1280x720[F8F6F8A2].extension


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    for I in "*.mp4" do;
    script qui renomme mes fichiers; 
    done
    et la sortie le résultat serait
    01.mp4
    02.mp4

  6. #6
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 283
    Par défaut
    Bonjour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ ls *.mp4
    [nomteam]nom de la série_01(1280x720[F8F6F8A2].mp4  [nomteam]nom de la série_02(1280x720[F8F6F8A2].mp4
    $ rename 's/.*_([^\(]*)\(.*/$1.mp4/' *.mp4
    $ ls *.mp4
    01.mp4  02.mp4

  7. #7
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 137
    Par défaut
    Merci Flodelarab pour le script mais j'ai pas compris la requête avec sed. je suis preneur d'explication

    Du coup j'ai refais mon script , alors j'arrive bien à extraire le numéro de l'épisode mais n'arrive pas à ajouter l'extension.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #!/bin/bash
     
    for fichier in *.mp4
    do 
    fic="$(sed 's/.* \([0-9.]\{1,\}\) .*/\1/g' <<< "${fichier}")" 
    mv "${fic}" "basename $fic .mp4"
    done
    Merci

  8. #8
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 283
    Par défaut
    Est-ce que j'ai utilisé une boucle for ? Non.
    Est-ce que j'ai utilisé sed ? Non.

  9. #9
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 137
    Par défaut
    Est-ce que j'ai utilisé une boucle for ? Non.
    Est-ce que j'ai utilisé sed ? Non.
    Le hic est que ton script ne faisait aucune action... c'est pour cela que j'ai pris cette solution.

  10. #10
    Membre éprouvé
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Juillet 2014
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2014
    Messages : 84
    Par défaut
    Citation Envoyé par schranz Voir le message
    Le hic est que ton script ne faisait aucune action... c'est pour cela que j'ai pris cette solution.
    si je peux me permettre :
    tu n'as pas dû bien lire la solution qu'il te propose.

    Je le cite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    rename 's/.*_([^\(]*)\(.*/$1.mp4/' *.mp4
    la commande : rename : merci captain obvious, elle permet de renommer des fichiers
    l'option 1 : 's/.*_([^\(]*)\(.*/$1.mp4/' , c'est une regex qui sera appliqué sur tous les éléments de la liste de l'option 2
    l'option 2 : *.mp4 , implicitement on liste tous les fichiers se terminant par '.mp4'

    Donc, pour tous les éléments de la liste 2 (on dirait une boucle for, non ?), la commande va renommer chaque élément en utilisant la regex pour modifier le nom du fichier.

    C'est une solution concise et intéressante.

  11. #11
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    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 102
    Par défaut
    Citation Envoyé par schranz Voir le message
    Du coup j'ai refais mon script , alors j'arrive bien à extraire le numéro de l'épisode mais n'arrive pas à ajouter l'extension.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #!/bin/bash
     
    for fichier in *.mp4
    do 
      fic="$(sed 's/.* \([0-9.]\{1,\}\) .*/\1/g' <<< "${fichier}")" 
      mv "${fic}" "basename $fic .mp4"
    done
    En admettant que le sed fasse bien ce que tu veux, il faut changer la ligne 'mv' en:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      echo mv "${fichier}" "${fic}.mp4"
    puis supprimer le 'echo' une fois que le script est bien sur le point de faire ce que tu veux.

    Mais tu peux aussi utiliser 'rename'!

  12. #12
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 137
    Par défaut
    jack-ft, merci mon script fonctionne !

    JeanMi3000, je vais refaire le script avec la commande rename mais je vois pas vraiment a corresponde certains passage de la commande

    la commande : rename : merci captain obvious, elle permet de renommer des fichiers
    l'option 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    's/.*_([^\(]*)\(.*/$1.mp4/'
    , c'est une regex qui sera appliqué sur tous les éléments de la liste de l'option 2
    si on peut juste m'expliquer sommairement cette partie ca serait super autant le point l'étoile et le ^derrière la parenthèse je connais ca signification mais le reste je vois pas son fonctionnement...

  13. #13
    Membre éprouvé
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Juillet 2014
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2014
    Messages : 84
    Par défaut
    Citation Envoyé par schranz Voir le message
    si on peut juste m'expliquer sommairement cette partie ca serait super autant le point l'étoile et le ^derrière la parenthèse je connais ca signification mais le reste je vois pas son fonctionnement...
    Je préférerais que ce soit Flodelarab qui te l'explique vu que c'est son code et ça m'éviterait d'écrire des âneries.

    's/.*_([^\(]*)\(.*/$1.mp4/'
    c'est donc une regex qui va faire une substitution (le 's' après l'apostrophe)
    Elle se décompose de la sorte
    .*_([^\(]*)\(.*
    et
    $1.mp4

    L'expression ".*_([^\(]*)\(.*" se décompose encore :
    .*_ : on va chercher/matcher n'importe quel caractère jusqu'à arriver sur un caractère de soulignement (underscore)
    ([^\(]*) : on cherche un motif qui ne contient pas de backslash, ni de parenthèse ouvrante
    \(.* : le motif précédent doit être suivi d'une parenthèse ouvrante puis par n'importe quelle chaine de caractères
    Le quantificateur '*' permet de matcher 0 ou n'importe quelle occurrence.

    $1.mp4 :
    C'est l'expression par laquelle sera remplacée l'expression précédente
    $1 est une référence arrière, ici on demande au moteur qui gère l'expression de remplacer $1 par le premier motif ($2 pour le second ... ), il s'agit bien sur du motif issu de la première partie de l'expression

    Si on l'applique à :
    nom de la série_01(1280x720[F8F6F8A2].mp4
    .*_ == nom de la série_
    ([^\(]*) == 01 /*Ceci est est le motif qui sera utilisé par $1*/
    \(.* == (1280x720[F8F6F8A2].mp4

    nom de la série_01(1280x720[F8F6F8A2].mp4 devient 01.mp4

    Nom : sorry.jpg
Affichages : 4787
Taille : 38,0 Ko

  14. #14
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 335
    Par défaut
    Bonjour,

    Citation Envoyé par JeanMi3000 Voir le message
    .*_ : on va chercher/matcher n'importe quel caractère jusqu'à arriver sur un caractère de soulignement (underscore)
    Juste un petit rajout sur l'explication qui est déjà plus que correcte:
    Ici, il faut se méfier de la "gourmandise" de '*' et qui va donc chercher la plus grande expression valide, donc si tu as N underscore, il retournera la chaine contenant tous les underscores (en tenant compte bien sur de la totalité de la regex).
    En gros si tu as:
    toto_titi_série_01
    il prendra en compte "toto_titi_série_" et non pas seulement "toto_".

  15. #15
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 283
    Par défaut
    J'avais moyennement envie de répondre car les réponses sont dans n'importe quel memento sed.

    La regex (regular expression = expression régulière) est une chaîne de caractère dont une partie est interprétable. Ici, la regex n'est que dans le premier compartiment de la substitution, à proprement parlé.

    s/blabla/bloblo/ remplace blabla par bloblo
    mais s@blabla@bloblo@ aussi
    et s|blabla|bloblo| aussi
    et s#blabla#bloblo# aussi
    et s,blabla,bloblo, aussi
    Le séparateur peut être changé en fonction du contexte (chemin de fichier avec dossiers séparés par / , par exemple)

    Maintenant, à la place de blabla, on va mettre la fameuse regex.
    . n'importe quel caractère
    .* n'importe quel caractère en quantité de 0 à l'infini (les quantificateurs dans les regex se situent après l'objet que l'on veut quantifier, ici, un caractère)
    .*_ n'importe quel chaine de caractère (la plus grande possible) jusqu'à un tiret bas.

    [liste] un seul caractère issu d'une liste de caractères possibles (ici l ou s ou e par exemple)
    [^liste] un seul caractère qui n'est pas dans la liste (ici a, b ou z)
    [^a-z] un caractère qui n'est pas une minuscule.
    [^(] un caractère qui n'est pas une parenthèse.
    [^\(] un caractère qui n'est pas une parenthèse.

    Pour former un groupe, il faut utiliser des parenthèses.
    Question: Quand on écrit une parenthèse, est-elle interprétée comme groupe ou comme caractère ?
    Réponse: Manifestement, ça dépend. De l'environnement.
    Dans sed (sans option) \(groupe\) est un groupe et (groupe) est une chaine entre parenthèse.
    Dans rename, ça semble être le contraire.

    On reprend:
    .*_.*(.* une chaine contenant un tiret bas et une parenthèse (le dernier tiret bas et la dernière parenthèse)
    .*_([^\(])\(.* une chaine contenant un tiret bas suivi d'un groupe contenant un seul caractère n'étant pas une parenthèse puis une parenthèse.
    .*_([^\(]*)\(.* une chaine contenant un tiret bas suivi d'un groupe contenant autant de caractères qu'on veut tant que ce n'est pas une parenthèse, et suivi d'une parenthèse.
    .*_([^\(]*)\(.* une chaine contenant un tiret bas et une parenthèse (dernier tiret bas et premiere parenthèse après le tiret bas). Entre les deux, un groupe.

    Et bien voilà, on a fini blabla. Passons à bloblo.
    Le fait de faire des groupes permet d'utiliser des quantificateurs sur un groupe. Par exemple, \(tota\)* doit renvoyer une correspondance pour totatotatota.
    Mais ils servent aussi à faire des références arrières. C'est-à-dire à réutiliser les blocs déjà identifiés.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ sed 's,\(tota\)*,glo,' <<<"totatotatotabal"
    global
    $ sed 's,\(tota\).*\1,glo,' <<<"totatotatotabal"
    global
    J'ai volontairement mis la référence dans blabla car c'est inhabituel. D'habitude, on n'en a besoin dans bloblo.
    La chaine ciblée est n'importe quoi qui commence par tota et fini par tota.

    Dans sed, les références arrières sont une contre-oblique suivi de la position du groupe. Attention! Les nombres à 2 chiffres (ou plus) sont interdits. \1 ou \5 ou \9 mais pas \10.
    Dans rename, c'est un dollar suivi du numéro. Le fait de mettre un \1 provoque un avertissement.

    En conclusion, on comprend que l'on va renommer des fichiers d'extension 'mp4' en substituant tout par la chaine de caractère entre le tiret bas et la première parenthèse trouvée à laquelle on adjoint l'extension 'mp4' puisqu'elle à disparue.

    Ouf!

    PS: Il ne faut pas confondre les regex et les caractères jokers (wildcard).
    *.mp4 utilise * comme un joker pouvant être n'importe quelle chaine dans le nom de fichier. Ce n'est pas une expression régulière!
    *.mp? va correspondre à *.mp2 *.mp3 *.mp4

  16. #16
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 137
    Par défaut
    Merci pour toute ces explications claire à tous !!

    je vais m'en servir pour refaire mon script sur un autre type de nommage .

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 09/01/2019, 21h23
  2. Script shell pour renommer des fichiers dans des sous répértoires
    Par ibuto dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 25/12/2013, 20h52
  3. script pour rendre des fichiers cachés visibles
    Par yucef83 dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 21/03/2008, 15h15
  4. Choix pour un script pour effacer des fichiers
    Par mindover280 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 22/07/2007, 23h42
  5. 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

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