[Linux-bruxelles] script conversion minuscule-majuscule

Frederic Peters fpeters at entrouvert.com
Mer 10 Jan 22:13:18 CET 2007


axel leroy écrivait :

> supposons que je n'ai pas d'accents dans les noms de fichiers, comment je fais
> ensuite (je debute dans le monde de linux)

Avant tout je rappellerai qu'il est d'usage sur cette liste d'écrire à
l'endroit, c'est-à-dire de placer la réponse en dessous de la
question, tout en limitant la copie de la question aux besoins de
citation.

Ensuite, je reviendrais sur ton premier message, « je voudrais écrire
un script ».  Est-ce bien écrire un script que tu voudrais ou
seulement avoir un script effectuant la tâche demandée ?

Demander un tel script, c'est facile, et avoir une réponse avec le
script en question attaché, aussi.  Mais si ton objectif est
d'apprendre à écrire des scripts, une meilleure route est d'y aller
petit à petit.

Je considère ici qu'on parle de script shell, mais la tâche peut
évidemment être réalisée avec d'autres langages.  Je considèrerai
également que tu utilises bash.

  « le nom des fichiers situés dans un répertoire dont l’emplacement
  est passé comme deuxième paramètre. »

Pour avoir les noms des fichiers situés dans un répertoire, tu connais
déjà certainement la commande, c'est ls.  Ensuite pour accéder aux
paramètres passés à un script, il faut utiliser $1, $2, $3...

Donc lister le contenu d'un répertoire passé en second paramètre, ce
serait ls $2

Maintenant, tu as une tâche à réaliser sur chacun de ces fichiers,
comment passer un par un sur ceux-ci pour exécuter une commande ?

Le shell offre plusieurs possibilités d'effectuer des boucles, dans le
cas présent, je te propose la suivante :

for F in $(ls $2)
do
        echo $F
done

Que se passe-t-il ici ?  ls $2 va être exécuté et son contenu va être
traité par la boucle, affectant à la variable F un nom de fichier,
puis le suivant, et ainsi de suite.  [1]

On a là une structure de base, utile.  Passons au reste du problème :

  « convertir en majuscules ou en minuscules »

Dans un premier temps, contentons-nous de la conversion en minuscules,
comment cela peut-il se faire ?  Grâce à la commande tr que je
pointais dans ma première réponse.

tr permet notamment de remplacer des caratères par des autres, exemple :

 $ echo "abc cab" | tr [abc] [def]
def fde

Les a sont remplacés par des d, les b par des e et les c par des f.

Comme beaucoup de commandes UNIX, tr travaille avec ce qu'on appelle
l'entrée standard, ou stdin, et affiche son résultat sur la sortie
standard, ou stdout.

Le pipe (|) permet de passer la sortie d'une commande vers l'entrée 
d'une autre; ici je passe la sortie de echo à l'entrée de tr.

Pour en revenir à tr, pour convertir des majuscules aux minuscules, il
faudrait faire
  tr [ABCDEFGHIJKLMNOPQRSTUVWXYZ] [abcdefghijklmnopqrstuvwuyz]

Ce qui est limite long, alors il y a un raccourci possible :

 $ echo cvsNGEqem | tr [A-Z] [a-z]
cvsngeqem


On en est donc au point de savoir exécuter la même commande sur
plusieurs fichiers, et de connaître la commande qu'on veut effectuer,
il suffit de mettre le tout ensemble.

for F in $(ls $2)
do
    mv $F $(echo $F | tr [A-Z] [a-z])
done

La commande exécutée est mv, qui déplace/renomme un fichier, le
premier paramètre qu'on lui passe est le fichier récupéré de ls et le
second paramètre est la destination, dans le cas présent créée à
partir du nom de fichier, converti de majuscules en minuscules.  [2]


Il reste une question à ta demande initiale, c'est que le premier
paramètre, il faudrait qu'il serve à indiquer si on veut une
conversion vers les majuscules ou vers les minuscules.  Ça permet
d'introduire la manière d'effectuer un traitement conditionnel, avec
l'instruction 'if'.

if [ "$1" = "--vers-majuscules" ]
then
        ARG1="[a-z]"
        ARG2="[A-Z]"
else
        ARG1="[A-Z]"
        ARG2="[a-z]"
fi

Pour ensuite appeler "tr $ARG1 $ARG2".  [3]

Tu peux avoir la liste ds tests possible dans la page de manuel de
test (man 1 test).  On peut par exemple y lire :

    STRING1 = STRING2     the strings are equal
    STRING1 != STRING2    the strings are not equal

Mais aussi :

    -e FILE               FILE exists

qui pourrait être utile pour résoudre le problème exposé dans le point [2].



Voilà voilà, le script est maintenant écrit, et j'espère que les
explications auront été utiles, à toi, à d'autres.


        Frédéric



[1] et ça posera des problèmes s'il y a des espaces dans un fichier,
    mais je ne vais pas compliquer plus que ça l'explication.

[2] et ici il y aura des messages d'erreur quand le fichier d'origine
    sera déjà entièrement composé de minuscules, donc c'est pas super
    propre.

[3] et là sur la comparaison, c'est encore un gros raccourci pour
    raisons pédagogiques.




Plus d'informations sur la liste de diffusion Linux-bruxelles