Le Lundi 21 Octobre 2002 23:51, vous avez �crit :
> On Mon, 21 Oct 2002 14:44:07 +0200
> Bernard Lambey <[EMAIL PROTECTED]> wrote:
>
> ~~~~~~~~~~~~~~~~~~~~
> > Jipe! quand je parlais d'exemples l'autre jour... Dis? Ne
pourrais-tu
> > nous rendre le service de commenter longuement, largement et...
> > en travers ce programme bash. Je crois que tu ferais grand plaisir
> > � ceux qui, comme moi, essaient de comprendre qqchose au bash...
> > Merci
> > Bernard L.
> > --
>
> pourquoi pas ?
> par contre, permets moi de changer le titre du fil... bash contre
perl ? surtout pas. non seulement pour ne pas r�veiller tous les
trolls de la montagne, mais aussi parce que �a n'a pas lieu d'�tre...
ni contre python ou ruby. et puis le script en question est un peu
une r�invention du fil � couper le beurre. juste un d�fi amusant �
relever.
>
> donc voici la b�te:
>
> #!/bin/bash
>
> IFS=$(echo -e "\r")
>
> i=$(cat $1)
> a=0
>
> while [ $a -lt ${#i} ]
> do
> b=${i:$a:1}
> case ${i:$a:8} in
> \<[aA]\ [hH][rR][eE][fF]=)
> echo -n "${i:$a:8}"
> a=$((a+8))
> while true
> do
> b=${i:$a:1}
> case $b in
> \>)
> echo -n "$b"
> a=$((a+1))
> break
> ;;
> [A-Z])
> echo -n "$b" | tr
>[:upper:] [:lower:]
> a=$((a+1))
> ;;
> *)
> echo -n "$b"
> a=$((a+1))
> ;;
> esac
> done
> ;;
> *)
> echo -n "$b"
> a=$((a+1))
> ;;
> esac
>
> done
>
> echo
>
> qu'est-il sens� faire ?
>
> rechercher dans un fichier html les balises <a href=" "> quelle
que soit la casse de a href et changer les majuscules en minuscules
apr�s le = � l'int�rieur de ces balises.
>
> tout d'abord la base du script.
>
> il s'agit du script suivant que je vais d'abord analyser:
>
> #!/bin/bash
>
> IFS=$(echo -e "\r")
>
> i=$(cat $1)
> a=0
>
> while [ $a -lt ${#i} ]
> do
> b=${i:$a:1}
> echo -n "$b"
> a=$((a+1))
> done
>
> echo
>
> la 1�re ligne "#!/bin/bash" est appel�e shebang pour shell et bang
qui d�signe le "!". elle permet, lorsque le script est invoqu� par
son nom, d'appeler l'interpr�teur qui va bien. dans ce cas, le script
doit �tre ex�cutable. on peut s'en passer et appeler le script en
argument de l'interpr�teur: "/bin/bash script". dans ce cas, le
script n'a pas besoin d'�tre ex�cutable.
>
> la variable $IFS est par convention le s�parateur de champ interne.
elle permet de d�finir le ou les s�parateur de champ pour la suite du
script.
> dans le cas pr�sent, le s�parateur de champ sera le retour
charriot. ce qui permet d'inclure dans la variable $i, � la ligne
suivante, le tabulations et sauts de ligne rencontr�es par la
commande cat $1. elles �quivaudront � un caract�re.
>
> la 3�me ligne d�finit la variable $i. celle ci contient donc le
r�sultat de la commande "cat $1". $1 est le 1er argument fourni �
l'�vocation du script. tout fichier text devrait faire l'affaire.
>
> la 4�me ligne d�finit � 0 la variable $a qui a son utilit� dans la
boucle while qui suit.
>
> la boucle while donc. de la forme while condition; do commande;
done. ou, pour les non anglophones, tant que condition; faire
commande; fait.
>
> la condition:[ $a -lt ${#i} ]
> ${#i} correspond � la longueur de la chaine de caract�res contenue
dans $i. la boucle ne s'arr�tera que lorsque $a sera �gale � ${#i}.
>
> 1�re commande: b=${i:$a:1}
> petite digression... d�finissons $toto
> $ toto=abcdefghijklmnopqrstuvwxyz
> quelle est la longueur de $toto ?
> $ echo ${#toto}
> 26
> d�coupons $toto � partir du 20�me caract�re exclus, jusqu'� la fin
> $ echo ${toto:20}
> uvwxyz
> d�coupons 7 caract�res � partir du 3�me inclus
> $ echo ${toto:2:7}
> cdefghi
> donc b=${i:$a:1} va d�finir $b comme contenant une chaine de
caract�res partant de $a, au d�part 0, donc le 1er caract�re de $i et
de 1 caract�re. $a �tant indent� par la suite.
>
> 2�me commande: echo -n "$b"
> $b est affich� dans le terminal, ou dans un fichier si la sortie du
script est redirig�e vers un fichier avec > fichier.
> -n supprime le saut de ligne que rajoute normalement echo.
>
> 3�me commande: a=$((a+1))
> autre digression... bash permet des op�rations alg�briques simples
avec des nombres entiers.
> $ echo $((2+3))
> 5
> $ echo $((2*3))
> 6
> $ echo $((2/3))
> 0 <- attention! le r�sultat est un entier. donc valeur enti�re par
d�faut.
> $ echo $((2-3))
> -1 <- et l�, un entier n�gatif.
> $ echo $((2**3))
> 8
> etc...
> on peut utiliser des "()" comme dans toute expression alg�brique
> $ echo $((3-(2-1)))
> 2
> $ echo $(((3-1)*6+(2+2)**2))
> 28
> donc $a, qui valait 0 au d�part, vaudra a+1 pour la boucle
suivante. ce qui signifie qu'a chaque boucle, $b va se d�placer dans
la chaine $i de 1 caract�re, exactement comme un curseur...
>
> l'avant derni�re ligne "done", signifie la fin de la boucle, et la
derni�re "echo", permet seulement le retour � un prompt situ� en
d�but de ligne � la fin du script et non en bout de la ligne
pr�c�dente.
>
> maintenant que peut-on en faire ?
>
> dans le script de d�part, je cherche � trouver une chaine "<a
href=" quelle que soit la casse. je la fais chercher par un "case".
>
> case ${i:$a:8} in
> \<[aA]\ [hH][rR][eE][fF]=)
>
> le curseur $b se d�place dans $i en fonction de la valeur de $a. je
rappelle que b=${i:$a:1}. si les 8 caract�res � partir de $b, cad
${i:$a:8} (tout le monde suit?) correspondent � cette recherche,
mat�rialis�e par la ligne se terminant par ")", o� le "\" prot�ge le
"<" et l'espace d'une interpr�tation erron�e, et [aA] signifie a ou A
et ainsi de suite..., les actions suivantes vont �tre entreprises.
>
> echo -n "${i:$a:8}"
> a=$((a+8))
>
> les 8 caract�res � partir de $b vont �tre envoy�e vers la sortie,
�cran ou fichier et $a est augment�e de +8. le curseur $b se d�place
donc de 8 caract�res vers la droite.
>
> ensuite vient une autre boucle while toujours vraie "true", qui va
d�placer le curseur $b jusqu'a la fin de la balise ">" et changer les
majuscules en minuscules au passage.
>
> while true
> do
> b=${i:$a:1}
> # le curseur se d�place de 1 caract�re vers la droite
> case $b in
> \>)
> echo -n "$b"
> a=$((a+1))
> break
> ;;
> # si le signe ">" est rencontr�, la boucle while est rompue avec
break
> [A-Z])
> echo -n "$b" | tr [:upper:] [:lower:]
> a=$((a+1))
> ;;
> # si un caract�re majuscule est rencontr�, il est tranform� en
minuscule grace � tr
> *)
> echo -n "$b"
> a=$((a+1))
> ;;
> # dans les autres cas, rien de sp�cial ne se passe
> esac
> done
>
> � chaque fois, bien sur, $a est augment� de 1 pour d�placer le
curseur et le r�sultat envoy� vers la sortie, �cran ou fichier.
>
> dans le 1er cas, donc, des actions ont �t� d�finies si les 8
caract�res qui suivent le curseur correspondent au motif de la
recherche. actions contenues dans une boucle while et un case. il
faut bien ensuite d�finir ce qui se passe, s'ils ne correspondent
pas! c'est le 2�me cas...
>
> *)
> echo -n "$b"
> a=$((a+1))
> ;;
>
> le * signifie "n'importe quoi" ou plut�t "dans tous les autres
cas". c'est forc�ment le dernier motif de recherche, lorsque tous les
cas particuliers ont �t� recherch�s. donc dans tous les autres cas,
on envoye $b vers la sortie, et on augmente $a de 1 pour d�placer le
curseur.
>
> voil�! on peut faire plein d'autres choses. du plus simple, comme
compter le nombre de fois o� apparaissent les noms des doctes Nanard,
Ismael ou Didier dans un fichier, ou de plus compliqu�es comme leur
adjoindre une balise <I> </I> ainsi qu'un nombre de 1 � 3 en fonction
du 1er rencontr�, puis du 2�me, puis du 3�me et qui leur soit propre
tout au long du fichier et permette de renvoyer � un commentaire en
fin de page concernant leur vie, leur oeuvre et leurs travers
secrets...
>
> en esp�rant avoir r�pondu � votre demande!
> bye
> jipe
Merci jipe !!
--
a+
al@in
Vous souhaitez acquerir votre Pack ou des Services MandrakeSoft?
Rendez-vous sur "http://www.mandrakestore.com"