• [^] # Re: jette un oeil a man rename

    Posté par . En réponse au message Expression rationnelle - Majuscule/Miniscule. Évalué à 3.

    > D'une certaine façon, plus j'augmente les indices, plus j'affine la
    > correspondance?

    Mmh, pas tout à fait, enfin ça dépend ce que tu entends par là :)
    Disons que, après l'utilisation d'un "=~", le tableau BASH_REMATCH contient :
    - à l'indice 0, la chaine qui a matché l'ensemble de la regexp. Ici, c'est le nom de fichier ($f) complet, puisque ma regexp va obligatoirement du début jusqu'à la fin de la chaine ('^' au début et '$' à la fin). Mais si j'avais fait par exemple [[ "123plop.MP3" =~ '([a-ZA-Z]+)\.([mM][pP]3)' ]], on aurait eu BASH_REMATCH[0] qui vaudrait "plop.MP3", puisque le "123" lui n'est pas dans le match.
    - aux indices >= 1, le tableau contient les sous-expressions marquées entre parenthèses dans la regexp. Ça permet de récupérer des morceau de chaines. Ici, BASH_REMATCH[1] correspond au groupe "([a-ZA-Z]+)", donc au nom du fichier (note que c'est pas une bonne regexp pour un nom de fichier, vu que tu as en fait probablement des espaces ou des trucs du genre). Et BASH_REMATCH[2] correspond au groupe "([mM][pP]3)", donc à l'extension. Et au delà de 2, il n'y aura rien puisqu'il n'y avait que 2 groupes.

    > J'en suis pas encore à un soucis d'optimisation

    Ouais, là je me doute un peu que tu n'as pas 10000 fichiers à renommer d'un coup, et que donc tu t'en fiches. Mais c'est clair qu'il est utile de connaitre quelques bashismes pour éviter les forks quand on fait des grosses boucles, sinon on arrive vite à des scripts qui passent de quelques dixièmes de secondes à quelques minutes en temps d'exécution. C'est des bonnes habitudes à prendre.
    Par exemple, sans parler même du =~ qui est encore un peu trop récent pour pouvoir être largement utilisé, prends par exemple les substitutions "simples" dans les chaines... Tu vois souvent des crougnes de ce genre là :

    find . -type f -name '*.MP3' \
    | while read f ; do
    mv "${f}" "`echo $f | sed 's/\.MP3$/.mp3/'`"
    done

    Bon, bah c'est affreusement lent (on crée, pour chaque nom de fichier, un premier sous-shell pour le `...`, puis deux autres processus pour les 2 côtés du pipe). Alors qu'on peut écrire sans fork inutile dans la boucle :

    find . -type f -name '*.MP3' \
    | while read f ; do
    mv "${f}" "${f%.MP3}.mp3"
    done

    Enfin voilà, ça c'est déjà un exemple plus réaliste d'un truc où un petit bashisme permet de faire bien mieux que du bourne shell de base.