Webmail Espace privé About
Home   Debian Addict Testing

Répétition

mercredi 2 novembre 2005.
 

Une petite introduction aux traitements par lots.

Problématique

Vous disposez d’un ensemble de fichiers qui nécessitent une action quelconque, la même, pour atteindre un état qui vous convient.

Exemples :
- vous disposez d’une bonne centaine de photographies numériques dont certaines seulement sont au format portrait et vous désirez toutes les retrouver au format paysage,
- vous voulez réduire la taille et/ou le format de fichier de plusieurs milliers d’images,
- modifier l’encodage de votre source LaTeX disséminé dans plusieurs fichiers appartenant eux-mêmes à plusieurs répertoires,
- ...

Bref, des petits soucis de tous les jours.

Les deux grands cas

On le voit ci-dessus, deux grandes familles se dessinent d’elles-mêmes :

  1. les fichiers nécessitant un traitement appartiennent au même répertoire,
  2. ou alors il faut les trouver dans une arborescence avant leur traitement.

Dans le premier cas, la seule difficulté va être de déterminer avec soin le traitement que va subir chaque fichier (quitte à en faire un petit fichier de commandes ayant au moins pour argument le nom du fichier à traiter).

Dans le second cas, nous allons d’abord devoir récupérer les noms (ainsi que le chemin) des fichiers avant de leur faire subir notre moulinette.

Pour les exemples ci-après, je propose une simple transformation de format d’image (png vers jpg) grâce à la formidable suite ImageMagick et plus particulièrement son outil convert. Enfin, je pars du principe que le shell employé est le bash.

Tous mes fichiers sont déjà dans le même répertoire

Je considère que ce répertoire ne contient que les fichiers qui m’intéressent pour la transformation. Ce répertoire est également mon répertoire courant. Je n’ai donc pas besoin de retrouver ces fichiers, j’ai simplement à effectuer une transformation (la même) pour chacun d’eux.

Pour ce faire, nous allons utiliser une boucle :

for var in ...
do cmd $var ...
done

avec cmd notre petite moulinette.

Ce qui nous donne dans le cas présent :

for i in *
do convert $i $i.jpg
done

Superbe ! A ceci près que mes fichiers destinations disposent maintenant de deux extensions : .png.jpg. Ce n’est pas du meilleur effet ! Comment puis-je me débarrasser de la première extension avant d’adjoindre l’extension finale ?
- par substitution : ${i/\.png/\.jpg} ;
- par effacement puis remplacement : ${i/\.png/}.jpg ;
- par effacement puis remplacement (2) : `basename $i png`jpg.

Je prends soin, pour les deux premières méthodes, de conserver le "." de l’extension : on ne sait jamais ce que peut contenir le nom de fichier à traiter. Enfin, afin de prendre toute la mesure de ce qui vient d’être fait, on se répétera quatre ou cinq fois : "Qu’est-ce que c’est puissant le shell !"

En fait, je dois transformer mes images, mais aussi effacer la version d’origine (si tout s’est bien passé) et envoyer les .jpg résultants à tonton ! Là encore, le bash est notre ami :

for i in *.png
  # je spécifie ici que je ne modifie que les .png
do convert $i ${i/\.png/\.jpg} && rm $i
  # je convertis et j'efface si la conversion est OK.
do uuencode ${i/\.png/\.jpg} ${i/\.png/\.jpg} | mail -s "Photo ${i/\.png/}" tonton@somewhere.com
  # je transforme l'image pour la transporter et je "maile"
  # l'ensemble avec un sujet parlant.
done

Autant regrouper ces commandes au sein d’un fichier pour faire plus propre et gagner en lisibilité :

#!/bin/bash
# PhotoBombing.sh
# envoyeur de photos v0.0001 béta
convert $1 ${1/\.png/\.jpg} && rm $1
uuencode ${1/\.png/\.jpg} ${1/\.png/\.jpg} | mail -s "Photo ${i/\.png/}" $2

L’appel se fera comme suit : for i in *.png ; do PhotoBombing.sh $i tonton@somewhere.com ; done Si toutefois PhotoBombing.sh est dans le PATH.

Attention : il faut bien avoir conscience que le script présenté ici est très sommaire. Il ne vérifie pas le nombre de ses arguments, ni la validité de ces derniers. En outre, il présuppose que l’on puisse envoyer des mails depuis le poste où il est exécuté. Le but est ici de comprendre la méthode. Libre à vous d’améliorer le principe et de l’agrémenter selon vos besoins.

Je ne sais pas où sont les fichiers à traiter

Pour les retrouver, je vais utiliser la commande find. Ici encore, j’ai besoin de retrouver tous mes .png pour les envoyer électroniquement à tonton sous forme .jpg.

Ça tombe bien, j’ai déjà sous la main une petite moulinette qui fait ça très bien pour moi. Il manque simplement la recherche des images d’origine. Elle se fait comme ceci : find /mon/chemin/de/recherche -iname "*.png" -exec PhotoBombing.sh {} tonton@somewhere.com \;

Le -iname est là pour m’assurer que je trouverai aussi les .PNG (si vous avez encore des partitions vfat, ça arrive !)

-exec me permet de lancer une commande pour tous les fichiers répondant au critère de recherche ; chaque fichier rencontré est accessible par {}. Enfin, le \; permet de terminer la ligne de commande du find.

Notons qu’il existe une option proche de -exec : -ok qui demande confirmation à l’utilisateur avant d’exécuter la commande qui la suit.


Ces exemples étaient purement fictifs. Ils étaient simplement là pour étayer le propos.

Les méthodes présentées ci-dessus permettent des manipulations totalement inenvisageables avec l’interface graphique seule.

Notez toutefois que l’on peut judicieusement concilier les deux. Dans le répertoire où vous engrangez jalousement les petites vidéos sympa que vous recevez par mail, essayez donc ceci :

for i in * ; do vlc $i ; done

Vous n’aurez plus besoin de cliquer sur chacun des fichiers pour les visualiser ; le fait de fermer vlc à la fin du clip vous lancera automatiquement le suivant.


Une dernière recommandation : je vous invite à user de la commande echo avant de lancer le traitement réel, ça permet de prévenir une calvitie précoce !

for i in *
do echo rm -rf $i
done

Le bash est puissant et echo est votre ami !


Signatures: 0
Date Nom Message

Forum

Vous pouvez participer à la vie de ce site et proposer vos propres articles en vous inscrivant ci-dessous. Vous recevrez immédiatement un email vous indiquant vos codes d'accès à l'espace privé du site.

Identifiants personnels

Indiquez ici votre nom et votre adresse email. Votre identifiant personnel vous parviendra rapidement, par courrier électronique.

Des mêmes auteurs