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 de renommage en sh avec contrainte d'environnement [Débutant(e)]


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Novembre 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 21
    Par défaut Script de renommage en sh avec contrainte d'environnement
    Bonjour.

    Je suis débutant en scripting shell, je cherche depuis 2 jours à trouver des solutions pour créer mon script mais là je suis quelque peu bloqué. j'ai du voir la solution sans la trouvé

    Je souhaite faire un script me permettant de renommer les noms de fichiers de mes séries, le plus générique possible.

    Contrainte : environnement linux SYNOLOGY (donc certaines commandes ne sont pas disponible tel que : "TR")

    Le code est peut être fouillis pour un dev qui respect des normes de nomenclatures.

    Voici mon code actuel :

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #!/bin/sh
    OLD_IFS="$IFS";
    IFS=$'\n';
     
    if [ $# -le 2 ]; then
    	cd $1
    	#cdResult=`cd $1`
     
    #	if [ $cdResult -qe false ]; then
    		EpisodeNumber=1;
    		printf "le répertoire courant est désormais : "`pwd`
    		read key
     
    		printf "Saisissez le nom de la série : "
    		read NomDeSerie
    		printf "Le nom de la série est donc : "$NomDeSerie
    		read key
     
    		#printf "Saisissez l'extension (exemple: avi): "
    		#read ext
     
    		for Filename in $(ls *.avi *.mp4 *.mkv);
    		do
    			ext=`expr "$Filename" : ".*\(...\)"`
    			#i=`echo $Filename | awk {'print tolower($_)'}`
    			if [ $EpisodeNumber -le 9 ] ; then 
    				mv $Filename $NomDeSerie"0"$EpisodeNumber.$ext; 
    			else 
    				mv $Filename $NomDeSerie$EpisodeNumber.$ext; 
    			fi
    			EpisodeNumber=$(($EpisodeNumber + 1));
    		done;
    #	else
    #		echo "erreur : Le répertoire est invalide"
    #	fi
    else
    	echo "Il faut saisir le nom du répertoire :  "$0" <nom du répertoire ou chemin complet> "
    fi
    cd ..
    IFS="$OLD_IFS";
    J'aimerais de l'aide pour matcher une valeur d'une string contenu dans une variable:

    Voici mon déroulement logique :

    Exemple nomenclature de fichier:
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    xxxxxxxxxS05E12.xxx
    xxxxxxxxxxxxxxs05e12.xxx
    xxxxxxxxx512.xxx
    xxxxx05x12.xxx
    
    Ou je me situe ?
    si dossier: ok alors : déplacement dans le dossier
    sinon (output de la commande CD): erreur préciser nom de dossier
    
    logique :
    
    saison = ?
    episode = ?
    
    chaine = chaine en minuscule
    
    1. si 
    s - nombre -> saison
    e - nombre -> episode
    2. si
    nombre - x - nombre => saison - x - episode
    3. detecterai les nombres
     -> si entre 100 et 1000 alors
     1er charactere = saison
     les autres = episode
    
    En gros ça fera ça : 
     
    $nomdeserie = scanf()
     
     for ($origin in $(ls))
     do
     
    	$tmp = Minuscule($origin) # ca je l'ai
    	$saison = 0
    	$episode = 0
    	
    	if [1] then
    	elif [2] then
    	elif [3] then
    	else
    		printf "error : " $origin
    
    	mv $origin $nomdeserie"S"$saison"E"$episode
    		
    	done
    Il est certainement plus facile de le faire en C, mais n'ayant aucune connaissance et souhaitant me familiarisé avec les commandes shell en général je préfère rester sur le shell.

    Je souhaiterais donc savoir quel commande (grep ? sed ? awk ? expr ? cut ?) utiliser pour matcher dans une variable la saison et l'épisode.

    Zt l'autre chose est que je n'arrive pas, en début de code, à récupérer l'output de la commande 'CD', de façon à pouvoir retourner une erreur si la saisie est erroné !

    Merci d'avance pour votre aide.

    PS : si c'est possible d'avoir les explication des commandes que vous me proposer que je comprenne et puisse les réutiliser ultérieurement.

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 56
    Par défaut
    Salut,

    Quand t'auras une solution, je te la piquerai volontiers !
    Un début de réponse : pour avoir le retour de cd, il faut utiliser $? qui donne le retour de la dernière fonction, exemple approximatif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    cd $(chemin)
    if [ $? -eq 0 ]
       #c'est bon
    Sinon, pour matcher les noms, il faut se tourner vers les expressions régulières mais je ne maitrise pas du tout et peut-être la commande rename si disponible sous ton environnement. Le lien est un peu laconique mais tu peux utiliser rename avec les expressions régulières.
    bon courage

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

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

    $'\n' n'existe pas en sh, c'est du bash.

    plutôt que de tester le retour de cd, pour tester qu'une variable est un répertoire :on ne fait pas for i in $(commande) outre d'éventuels espaces, les noms de fichiers (ici) peuvent contenir d'autres caractères invisibles, il vaut mieux utiliser le shell for i in liste, qui, lui, protègera les espaces, et autres caractères invisibles.

    matcher dans une variable la saison et l'épisode
    en les comparant à quoi?
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  4. #4
    Membre averti
    Inscrit en
    Novembre 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 21
    Par défaut
    Merci pour vos réponses.

    ok pour le test -d "$variable"

    je ne vois pas bien sur quelle variable l'appliquer hormis celle-ci : $1
    et du coup il y a possibilité d'avoir un code erreur de retour ?
    PS: j'ai trouvé ce lien pour le test du coup j'ai modifier mon code de la sorte
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if [ $# -le 2 ]; then
            cdResult=false;
    	test -d $1 && cdResult=true;
     
    	if [ $cdResult == true ]; then
    		cd $1
    		EpisodeNumber=1;
    [...]
    du coup ça fonctionne bien
    Il vaux donc mieux faire for i in liste
    Mais on remplace "liste" par quoi ? c'est une commande qui va lister le contenu du répertoire en retournant les noms des fichiers ?

    il faudrait donc faire quelque choses comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lsResult=`ls *.avi *.mkv`
    for Filename in lsResult;


    Cependant, j'avais mis ce code suite à des erreurs d'espace justement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    OLD_IFS="$IFS";
    IFS=$'\n';
    en l'enlevant, je retrouve les erreurs dû au espace dans les nom de fichier avec ma boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for Filename in $(ls *.avi *.mkv);


    Pour ce qui est de matcher, ce n'est peut être pas le bon terme que j'ai employé.
    je voudrais analyser ma variable qui contiendra donc le nom du fichier et en se basant sur ces possibilités là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    xxxxxxxxS05E12.xxx
    xxxxxxxxxxxxxxs05e12.xxx
    xxxxxxxxx512.xxx
    xxxxx05x12.xxx
    en déduire la saison et l'épisode.
    j'espère être assez clair.

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    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 103
    Par défaut
    Citation Envoyé par fifyx Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    xxxxxxxxS05E12.xxx
    xxxxxxxxxxxxxxs05e12.xxx
    xxxxxxxxx512.xxx
    xxxxx05x12.xxx
    en déduire la saison et l'épisode.
    j'espère être assez clair.
    sed, c'est dien pas compliqué:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    case "${filename}" in
        *[Ss][0-9][0-9][Ee][0-9][0-9].???) # cas 1 et 2
            saison=$(echo "${filename}" | sed -e 's:.*[Ss]\([0-9][0-9]\)[Ee][0-9][0-9]\....$:\1:')
            episode=$(echo "${filename}" | sed -e 's:.*[Ss][0-9][0-9][Ee]\([0-9][0-9]\)\....$:\1:')
            ;;
        *[0-9][0-9]?[0-9][0-9].???) # cas 4
            saison=$(echo "${filename}" | sed -e 's:.*\([0-9][0-9]\).[0-9][0-9]\....$:\1:')
            episode=$(echo "${filename}" | sed -e 's:.*[0-9][0-9].\([0-9][0-9]\)\....$:\1:')
            ;;
        *[0-9][0-9][0-9].???) # cas 3
            saison=$(echo "${filename}" | sed -e 's:.*\([0-9]\)[0-9][0-9]\....$:\1:')
            episode=$(echo "${filename}" | sed -e 's:.*[0-9]\([0-9][0-9]\)\....$:\1:')
            ;;
    esac
    En fait, c'est plus facile à écrire qu'à lire!

    Edit: Attention! C'est \1 partout!

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 692
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if [ $# -le 2 ] # si nb2paramètre_du_script inférieur ou égal à 2; alors
    then
       test -d "$1" && cd "$1" # ne pas oublier les guillemets
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for f in *.avi *.mp4 *.mkv
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Membre averti
    Inscrit en
    Novembre 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 21
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    sed, c'est dien pas compliqué:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    case "${filename}" in
        *[Ss][0-9][0-9][Ee][0-9][0-9].???) # cas 1 et 2
            saison=$(echo "${filename}" | sed -e 's:.*[Ss]\([0-9][0-9]\)[Ee][0-9][0-9]\....$:\1:')
            episode=$(echo "${filename}" | sed -e 's:.*[Ss][0-9][0-9][Ee]\([0-9][0-9]\)\....$:\2:')
            ;;
        *[0-9][0-9]?[0-9][0-9].???) # cas 4
            saison=$(echo "${filename}" | sed -e 's:.*\([0-9][0-9]\).[0-9][0-9]\....$:\1:')
            episode=$(echo "${filename}" | sed -e 's:.*[0-9][0-9].\([0-9][0-9]\)\....$:\2:')
            ;;
        *[0-9][0-9][0-9].???) # cas 3
            saison=$(echo "${filename}" | sed -e 's:.*\([0-9]\)[0-9][0-9]\....$:\1:')
            episode=$(echo "${filename}" | sed -e 's:.*[0-9]\([0-9][0-9]\)\....$:\2:')
            ;;
    esac
    En fait, c'est plus facile à écrire qu'à lire!
    tu pourrais m'expliquer un peu s'il te plait pourquoi utilise tu un "case" ?
    et le sed :p

    -------------------------------------------------------------------------------------
    Citation Envoyé par N_BaH Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if [ $# -le 2 ] # si nb2paramètre_du_script inférieur ou égal à 2; alors
    then
       test -d "$1" && cd "$1" # ne pas oublier les guillemets
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for f in *.avi *.mp4 *.mkv
    j'ai modifié mon message précédent plutôt que de le remettre ici.
    Mais pourquoi tu met
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    test -d "$1" && cd "$1"
    ce que j'ai mis n'est pas correct ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if [ $# -le 2 ]; then
    	cdResult=false;
    	test -d "$1" && cdResult=true;
     
    	if [ $cdResult == true ]; then

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 692
    Par défaut
    ce que j'ai mis n'est pas correct ?
    pourquoi passer par une variable intermédiaire ?

    case permet d'utiliser des motifs génériques; ce que ne permet pas test.

    le problème avec les espaces vient de l'utilisation de ls; fais comme je t'ai montré, et mets des guillemets autour de tes variables !
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    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 103
    Par défaut
    Citation Envoyé par fifyx Voir le message
    tu pourrais m'expliquer un peu s'il te plait pourquoi utilise tu un "case" ?
    et le sed :p
    Comme tu présentes 4 formats différents de nom de fichier, je fais un "case" qui s'adapte à chacun de ces 4 cas (en fusionnant les 2 premiers).
    Logique, non?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    saison=$(echo "${filename}" | sed -e 's:.*[Ss]\([0-9][0-9]\)[Ee][0-9][0-9]\....$:\1:')
    Explication du sed:
    .* Chercher n'importe quel caractère (.) en nombre quelconque (*), suivi de
    [Ss] un caractère S ou s, suivi de
    [0-9][0-9] un caractère entre 0 et 9, suivi d'un caractère entre 0 et 9,
    \([0-9][0-9]\) au passage, à cause des parenthèses backslashées, numéroter la sous-chaîne correspondante comme 1 (car c'est la première backslashée rencontrée)
    suivi de
    [Ee][0-9][0-9] un caractère E ou e, suivi d'un caractère entre 0 et 9, suivi d'un caractère entre 0 et 9, suivi de
    \. un caractère point (.), suivi de
    ... trois caractères quelconques (.), suivis de
    $ la fin de la ligne (ou de la chaîne).

    Une fois que sed a trouvé la bête et numéroté ses sous-expressions (une seule, ici),
    's:<le tout>:\1:' remplacer le tout par la première sous-expression (\1)

    C'est clair, chef?

Discussions similaires

  1. script envoi mail et fax avec CDO
    Par RobinNono dans le forum ASP
    Réponses: 1
    Dernier message: 03/10/2005, 16h36
  2. UPDATE avec contraintes
    Par Ar-t dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 21/03/2005, 16h20
  3. [Debutant]Suppression dans des tables avec contraintes
    Par Roming22 dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 26/10/2004, 18h23
  4. SELECT : extraire 2 val d'1 colonne avec contraintes diff
    Par NiBicUs dans le forum Langage SQL
    Réponses: 3
    Dernier message: 29/03/2004, 15h56
  5. Script test de deux chaine avec if
    Par kacedda dans le forum Linux
    Réponses: 6
    Dernier message: 02/05/2003, 16h38

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