1 |
cam 08/10/12 20:35:28 |
2 |
|
3 |
Modified: l-awk1.xml |
4 |
Added: l-awk2.xml |
5 |
Log: |
6 |
#241610 New translation: /doc/fr/articles/l-awk2.xml thanks to Christophe LEFEBVRE |
7 |
|
8 |
Revision Changes Path |
9 |
1.2 xml/htdocs/doc/fr/articles/l-awk1.xml |
10 |
|
11 |
file : http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/fr/articles/l-awk1.xml?rev=1.2&view=markup |
12 |
plain: http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/fr/articles/l-awk1.xml?rev=1.2&content-type=text/plain |
13 |
diff : http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/fr/articles/l-awk1.xml?r1=1.1&r2=1.2 |
14 |
|
15 |
Index: l-awk1.xml |
16 |
=================================================================== |
17 |
RCS file: /var/cvsroot/gentoo/xml/htdocs/doc/fr/articles/l-awk1.xml,v |
18 |
retrieving revision 1.1 |
19 |
retrieving revision 1.2 |
20 |
diff -u -r1.1 -r1.2 |
21 |
--- l-awk1.xml 10 Oct 2008 23:54:55 -0000 1.1 |
22 |
+++ l-awk1.xml 12 Oct 2008 20:35:28 -0000 1.2 |
23 |
@@ -1,5 +1,5 @@ |
24 |
<?xml version="1.0" encoding="UTF-8"?> |
25 |
-<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/doc/fr/articles/l-awk1.xml,v 1.1 2008/10/10 23:54:55 cam Exp $ --> |
26 |
+<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/doc/fr/articles/l-awk1.xml,v 1.2 2008/10/12 20:35:28 cam Exp $ --> |
27 |
<!DOCTYPE guide SYSTEM "/dtd/guide.dtd"> |
28 |
|
29 |
<guide link="/doc/fr/articles/l-awk1.xml" lang="fr" disclaimer="articles"> |
30 |
@@ -420,11 +420,12 @@ |
31 |
<body> |
32 |
|
33 |
<ul> |
34 |
- <!--<li> |
35 |
- Lisez les autres articles de Daniel sur awk sur |
36 |
- developerWorks : Common threads: Awk by example, <uri |
37 |
- link="l-awk2.xml">Part 2</uri> and <uri link="l-awk3.xml">Part 3</uri>. |
38 |
- </li>--> |
39 |
+ <li> |
40 |
+ Lisez les autres articles de Daniel sur Awk publiés sur |
41 |
+ developerWorks : Common threads: Awk by example, <uri |
42 |
+ link="l-awk2.xml">Partie 2</uri><!-- et <uri link="l-awk3.xml">Part |
43 |
+ 3</uri>-->. |
44 |
+ </li> |
45 |
<li> |
46 |
Si vous recherchez un bon vieux livre, O'Reilly's <uri |
47 |
link="http://www.oreilly.com/catalog/sed2/">sed & awk, 2nd |
48 |
|
49 |
|
50 |
|
51 |
1.1 xml/htdocs/doc/fr/articles/l-awk2.xml |
52 |
|
53 |
file : http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/fr/articles/l-awk2.xml?rev=1.1&view=markup |
54 |
plain: http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/fr/articles/l-awk2.xml?rev=1.1&content-type=text/plain |
55 |
|
56 |
Index: l-awk2.xml |
57 |
=================================================================== |
58 |
<?xml version="1.0" encoding="UTF-8"?> |
59 |
<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/doc/fr/articles/l-awk2.xml,v 1.1 2008/10/12 20:35:28 cam Exp $ --> |
60 |
<!DOCTYPE guide SYSTEM "/dtd/guide.dtd"> |
61 |
|
62 |
<guide link="/doc/fr/articles/l-awk2.xml" lang="fr" disclaimer="articles"> |
63 |
<title>Awk par l'exemple, 2e partie</title> |
64 |
|
65 |
<author title="Auteur"> |
66 |
<mail link="drobbins@g.o">Daniel Robbins</mail> |
67 |
</author> |
68 |
<author title="Traducteur"> |
69 |
<mail link="clefebvre.62@××××.fr">Christophe Lefebvre</mail> |
70 |
</author> |
71 |
|
72 |
<abstract> |
73 |
Suite à son introduction à Awk, dans cette séquence, Daniel Robbins continue |
74 |
l'exploration d'Awk, le grand langage au nom étrange. Daniel va vous expliquer |
75 |
comment manipuler des enregistrements sur plusieurs lignes, utiliser les |
76 |
boucles et créer et utiliser des tableaux Awk. À la fin de cet article, vous |
77 |
aurez déjà vu une bonne partie des fonctionnalités d'Awk et vous serez prêt à |
78 |
écrire vos propres scripts avancés en Awk. |
79 |
</abstract> |
80 |
|
81 |
<!-- The original version of this article was published on IBM developerWorks, |
82 |
and is property of Westtech Information Services. This document is an updated |
83 |
version of the original article, and contains various improvements made by the |
84 |
Gentoo Linux Documentation team --> |
85 |
|
86 |
<version>1.4</version> |
87 |
<date>2005-10-31</date> |
88 |
|
89 |
<chapter> |
90 |
<title>Enregistrements, boucles et tableaux</title> |
91 |
<section> |
92 |
<title>Les enregistrements sur plusieurs lignes</title> |
93 |
<body> |
94 |
|
95 |
<p> |
96 |
Awk est un excellent outil pour lire et traiter des données structurées, comme |
97 |
le fichier système <path>/etc/passwd</path>. <path>/etc/passwd</path> est la |
98 |
base de données UNIX des utilisateurs. C'est un fichier texte délimité par des |
99 |
":", contenant beaucoup d'informations importantes, incluant entre autres tous |
100 |
les comptes et les ID des utilisateurs. Dans <uri |
101 |
link="/doc/fr/articles/l-awk1.xml"> mon article précédent</uri>, je vous ai |
102 |
montré comment Awk pouvait facilement traiter les différents champs de ce |
103 |
fichier. Tout ce que nous avions à faire était d'assigner ":" à la variable FS |
104 |
(séparateur de champs). |
105 |
</p> |
106 |
|
107 |
<p> |
108 |
En renseignant correctement la variable FS, Awk peut être configuré pour |
109 |
traiter les différents champs de n'importe quelle sorte de données structurées, |
110 |
tant qu'il y a un enregistrement par ligne. Cependant, FS ne sera pas suffisant |
111 |
si nous voulons traiter les différents champs d'un enregistrement qui sont sur |
112 |
plusieurs lignes. Dans ces situations, nous avons aussi besoin de modifier la |
113 |
variable séparatrice d'enregistrements RS (Record Separator). La variable RS |
114 |
indique à Awk quand l'enregistrement courant se termine et que le suivant |
115 |
commence. |
116 |
</p> |
117 |
|
118 |
<p> |
119 |
Par exemple, regardez comment nous faisons pour traiter une liste d'adresses de |
120 |
participants du « Federal Witness Protection Program » : |
121 |
</p> |
122 |
|
123 |
<pre caption="Exemple de données de la liste des participants du « Federal |
124 |
Witness Protection Program »"> |
125 |
Jimmy the Weasel |
126 |
100 Pleasant Drive |
127 |
San Francisco, CA 12345 |
128 |
|
129 |
Big Tony |
130 |
200 Incognito Ave. |
131 |
Suburbia, WA 67890 |
132 |
</pre> |
133 |
|
134 |
<p> |
135 |
Idéalement, nous souhaiterions qu'Awk reconnaisse chaque bloc de 3 adresses |
136 |
comme étant un enregistrement individuel, plutôt que 3 enregistrements séparés. |
137 |
Cela rendrait notre code un peu plus simple si Awk pouvait reconnaître la |
138 |
première ligne de l'enregistrement comme le premier champ ($1), les coordonnées |
139 |
de la rue comme le second champ ($2), la ville, l'état et le code postal comme |
140 |
troisième champ ($3). Le code suivant va simplement faire ce que nous |
141 |
voulons : |
142 |
</p> |
143 |
|
144 |
<pre caption="Réaliser l'initialisation d'un enregistrement de la liste |
145 |
d'adresse"> |
146 |
BEGIN { |
147 |
FS="\n" |
148 |
RS="" |
149 |
} |
150 |
</pre> |
151 |
|
152 |
<p> |
153 |
Ci-dessus, assigner "\n" à FS indique à Awk que chaque champ apparaît sur une |
154 |
ligne séparée. En assignant "" à RS, nous lui indiquons également que chaque |
155 |
enregistrement d'adresse est séparé par une ligne vide. Une fois qu'Awk sait |
156 |
comment les données en entrée sont formatées, il peut faire tous les |
157 |
traitements d'affichage de ces enregistrements que nous souhaitons. Et le reste |
158 |
du script est simple à écrire. Regardez ce script complet qui traite cette |
159 |
liste d'adresse et affiche chaque enregistrement correspondant à une adresse |
160 |
sur une simple ligne, séparant chaque champ avec une virgule. |
161 |
</p> |
162 |
|
163 |
<pre caption="Script complet"> |
164 |
BEGIN { |
165 |
FS="\n" |
166 |
RS="" |
167 |
} |
168 |
{ print $1 ", " $2 ", " $3 } |
169 |
</pre> |
170 |
|
171 |
|
172 |
<p> |
173 |
Si ce script est sauvegardé en <path>address.awk</path> et que les données |
174 |
correspondantes aux adresses sont stockées dans un fichier appelé |
175 |
<path>address.txt</path>, vous pouvez exécuter ce script en tapant <c>awk -f |
176 |
address.awk address.txt</c>. Ce code produit l'affichage suivant : |
177 |
</p> |
178 |
|
179 |
<pre caption="Les données affichées par le script"> |
180 |
Jimmy the Weasel, 100 Pleasant Drive, San Francisco, CA 12345 |
181 |
Big Tony, 200 Incognito Ave., Suburbia, WA 67890 |
182 |
</pre> |
183 |
|
184 |
</body> |
185 |
</section> |
186 |
<section> |
187 |
<title>OFS et ORS</title> |
188 |
<body> |
189 |
|
190 |
<p> |
191 |
Dans la directive d'affichage « print » du fichier |
192 |
<path>address.awk</path>, vous pouvez voir qu'Awk concatène (joint) les chaînes |
193 |
de caractères qui sont les unes à côté des autres sur une ligne. Nous avons |
194 |
utilisé cette fonctionnalité pour insérer une virgule et une espace (", ") |
195 |
entre les trois champs d'adresse qui apparaissent sur la ligne. Bien que cette |
196 |
méthode fonctionne, elle n'est pas très élégante. Plutôt que d'insérer des |
197 |
", " entre nos différents champs, Awk peut le faire pour nous grâce à une |
198 |
variable spéciale d'Awk appelée OFS, le séparateur des champs affichés |
199 |
« Output Field Separator ». Regardez cet extrait de code : |
200 |
</p> |
201 |
|
202 |
<pre caption="Exemple d'un extrait de code"> |
203 |
print "Hello", "there", "Jim!" |
204 |
</pre> |
205 |
|
206 |
<p> |
207 |
Les virgules sur cette ligne ne font pas partie de notre chaîne de caractères |
208 |
d'origine. Au lieu de cela, elles indiquent à Awk que "Hello", "there" et |
209 |
"Jim!" sont des champs séparés et que la variable OFS doit être affichée entre |
210 |
chaque chaîne de caractères. Par défaut, Awk produit le résultat suivant : |
211 |
</p> |
212 |
|
213 |
<pre caption="Affichage produit par Awk"> |
214 |
Hello there Jim! |
215 |
</pre> |
216 |
|
217 |
<p> |
218 |
Cela nous montre que par défaut, OFS vaut " ", une simple espace. |
219 |
Cependant, nous pouvons facilement redéfinir OFS, Awk insérera alors notre |
220 |
séparateur de champs favori. Voici une version modifiée de notre programme |
221 |
d'origine <path>address.awk</path> qui utilise OFS pour afficher ces caractères |
222 |
intermédiaires ", " : |
223 |
</p> |
224 |
|
225 |
<pre caption="Redéfinir OFS"> |
226 |
BEGIN { |
227 |
FS="\n" |
228 |
RS="" |
229 |
OFS=", " |
230 |
} |
231 |
{ print $1, $2, $3 } |
232 |
</pre> |
233 |
|
234 |
<p> |
235 |
Awk dispose aussi une variable spéciale appelée ORS, appelée le |
236 |
« séparateur des enregistrements affichés » (Ouput Record Separator). |
237 |
En renseignant ORS, qui vaut par défaut le caractère de nouvelle ligne ("\n"), |
238 |
nous pouvons contrôler le caractère qui sera automatiquement affiché à la fin |
239 |
d'une ligne. La valeur par défaut ORS oblige Awk à afficher chaque directive |
240 |
« print » sur une nouvelle ligne. Si nous voulons que les résultats |
241 |
soient séparés par une double ligne, nous affecterons alors "\n\n" à ORS. Ou, |
242 |
si nous voulons que les enregistrements soient séparés par une simple espace |
243 |
(et non par une nouvelle ligne), nous devons mettre ORS à " ". |
244 |
</p> |
245 |
|
246 |
</body> |
247 |
</section> |
248 |
<section> |
249 |
<title>D'un enregistrement multiligne formaté en enregistrement avec des |
250 |
tabulations</title> |
251 |
<body> |
252 |
|
253 |
<p> |
254 |
Disons que nous avons écrit un script qui convertit notre liste d'adresses vers |
255 |
le format : une ligne par enregistrement en délimitant les champs par des |
256 |
tabulations afin de pouvoir l'importer dans une feuille de calcul. Après avoir |
257 |
utilisé une version légèrement modifiée de <path>address.awk</path>, cela |
258 |
devient clair que notre programme ne fonctionne que pour des adresses composées |
259 |
de trois lignes. Si Awk rencontre l'adresse suivante, la quatrième ligne sera |
260 |
rejetée et ne sera pas affichée : |
261 |
</p> |
262 |
|
263 |
<pre caption="Exemple d'enregistrement"> |
264 |
Cousin Vinnie |
265 |
Vinnie's Auto Shop |
266 |
300 City Alley |
267 |
Sosueme, OR 76543 |
268 |
</pre> |
269 |
|
270 |
<p> |
271 |
Pour gérer de telles situations, ce serait bien si notre code prenait le nombre |
272 |
de champs par enregistrements en compte, affichant chacun d'entre eux dans |
273 |
l'ordre. Pour l'instant, le code affiche seulement les trois premiers champs de |
274 |
l'adresse. Voici un code qui fait ce que nous voulons : |
275 |
</p> |
276 |
|
277 |
<pre caption="Code amélioré"> |
278 |
BEGIN { |
279 |
FS="\n" |
280 |
RS="" |
281 |
ORS="" |
282 |
} |
283 |
|
284 |
{ |
285 |
x=1 |
286 |
while ( x<NF ) { |
287 |
print $x "\t" |
288 |
x++ |
289 |
} |
290 |
print $NF "\n" |
291 |
} |
292 |
</pre> |
293 |
|
294 |
<p> |
295 |
Tout d'abord, nous renseignons le séparateur de champs FS à "\n" et le |
296 |
séparateur d'enregistrements RS à "" afin qu'Awk analyse les adresses de |
297 |
plusieurs lignes correctement, comme auparavant. Alors, nous renseignons le |
298 |
séparateur d'affichage des enregistrements à "", ce qui demande à la directive |
299 |
« print » de ne pas afficher une nouvelle ligne à la fin de chaque |
300 |
appel. Cela signifie que si nous voulons qu'un texte commence sur une nouvelle |
301 |
ligne, nous avons besoin d'écrire explicitement « print "\n" ». |
302 |
</p> |
303 |
|
304 |
<p> |
305 |
Dans le bloc de code principal, nous créons une variable appelée x qui conserve |
306 |
le numéro du champ actuel que nous traitons. Initialement, il vaut 1. Alors, |
307 |
nous utilisons une boucle « while » (une boucle d'Awk qui est |
308 |
construite de la même façon que celle que l'on trouve dans le langage C) pour |
309 |
tout parcourir sauf le dernier enregistrement, afficher l'enregistrement et une |
310 |
nouvelle ligne ; aussi, depuis que ORS vaut "", « print » |
311 |
n'affiche plus de nouvelle ligne pour nous. Le résultat produit par le |
312 |
programme est le suivant, ce qui est exactement ce que nous voulons : |
313 |
</p> |
314 |
|
315 |
<pre caption="Notre résultat attendu. Pas très élégant, mais délimité par des |
316 |
tabulations pour une importation facile dans une feuille de calcul"> |
317 |
Jimmy the Weasel 100 Pleasant Drive San Francisco, CA 12345 |
318 |
Big Tony 200 Incognito Ave. Suburbia, WA 67890 |
319 |
Cousin Vinnie Vinnie's Auto Shop 300 City Alley Sosueme, OR 76543 |
320 |
</pre> |
321 |
|
322 |
</body> |
323 |
</section> |
324 |
<section> |
325 |
<title>Fonctionnement des boucles</title> |
326 |
<body> |
327 |
|
328 |
<p> |
329 |
Nous avons déjà vu le fonctionnement des boucles « while », qui est |
330 |
identique à son homologue en C. Awk a aussi une boucle « do...while » |
331 |
qui évalue la condition à la fin du bloc de code plutôt qu'au début comme une |
332 |
boucle « while ». C'est identique à une boucle |
333 |
« repeat...until » que l'on peut trouver dans d'autres langages. |
334 |
Voici un exemple : |
335 |
</p> |
336 |
|
337 |
<pre caption="Exemple « do...while »"> |
338 |
{ |
339 |
count=1 |
340 |
do { |
341 |
print "Peu importe, je serais affiché au moins une fois" |
342 |
} while ( count != 1 ) |
343 |
} |
344 |
</pre> |
345 |
|
346 |
<p> |
347 |
Parce que la condition est évaluée après le bloc de code, une boucle |
348 |
« do...while », à la différence d'une boucle normale |
349 |
« while », s'exécute toujours au moins une fois. Une boucle normale |
350 |
« while » ne s'exécutera jamais si sa condition est fausse à la |
351 |
première boucle. |
352 |
</p> |
353 |
|
354 |
</body> |
355 |
</section> |
356 |
<section> |
357 |
<title>Pour les boucles</title> |
358 |
<body> |
359 |
|
360 |
<p> |
361 |
Awk vous permet de créer des boucles, comme les boucles « while » |
362 |
sont identiques à leur homologue en C : |
363 |
</p> |
364 |
|
365 |
<pre caption="Exemple de boucle"> |
366 |
for ( assignement initial; comparaison; incrémentation ) { |
367 |
bloc de code |
368 |
} |
369 |
</pre> |
370 |
|
371 |
<p> |
372 |
Voici un exemple simple : |
373 |
</p> |
374 |
|
375 |
<pre caption="Exemple simple"> |
376 |
for ( x = 1; x <= 4; x++ ) { |
377 |
print "iteration",x |
378 |
} |
379 |
</pre> |
380 |
|
381 |
<p> |
382 |
Cet extrait affiche : |
383 |
</p> |
384 |
|
385 |
<pre caption="Résultat de l'extrait de code"> |
386 |
iteration 1 |
387 |
iteration 2 |
388 |
iteration 3 |
389 |
iteration 4 |
390 |
</pre> |
391 |
|
392 |
</body> |
393 |
</section> |
394 |
<section> |
395 |
<title>« Break » et « continue »</title> |
396 |
<body> |
397 |
|
398 |
<p> |
399 |
De plus, exactement comme en C, Awk fournit des directives « break » |
400 |
et « continue ». Ces directives fournissent un meilleur contrôle sur |
401 |
les différentes implémentations de boucles d'Awk. Voici un extrait de code qui |
402 |
a désespérément besoin d'une directive « break » : |
403 |
</p> |
404 |
|
405 |
<pre caption="Extrait de code ayant besoin d'une directive « break »"> |
406 |
while (1) { |
407 |
print "pour toujours et toujours..." |
408 |
} |
409 |
</pre> |
410 |
|
411 |
<p> |
412 |
Parce que 1 est toujours vrai, cette boucle se fera indéfiniment. Voici une |
413 |
boucle qui s'exécute seulement dix fois : |
414 |
</p> |
415 |
|
416 |
<pre caption="Boucle qui s'exécute seulement 10 fois"> |
417 |
x=1 |
418 |
while(1) { |
419 |
print "iteration",x |
420 |
if ( x == 10 ) { |
421 |
break |
422 |
} |
423 |
x++ |
424 |
} |
425 |
</pre> |
426 |
|
427 |
<p> |
428 |
Ici, la directive « break » est utilisée pour stopper la boucle la |
429 |
plus profonde. « break » termine donc immédiatement la boucle et |
430 |
l'exécution continue à la ligne après le bloc de code de la boucle. |
431 |
</p> |
432 |
|
433 |
<p> |
434 |
La directive « continue » complète « break » et fonctionne |
435 |
de cette façon : |
436 |
</p> |
437 |
|
438 |
<pre caption="La directive « continue » complète la directive |
439 |
« break »"> |
440 |
x=1 |
441 |
while (1) { |
442 |
if ( x == 4 ) { |
443 |
x++ |
444 |
continue |
445 |
} |
446 |
print "iteration",x |
447 |
if ( x > 20 ) { |
448 |
break |
449 |
} |
450 |
x++ |
451 |
} |
452 |
</pre> |
453 |
|
454 |
<p> |
455 |
Ce code affichera de « iteration 1 » jusqu'à « iteration |
456 |
21 », sauf « iteration 4 ». Si l'itération est égale à 4, x est |
457 |
incrémenté et la directive « continue » est appelée, ayant pour effet |
458 |
qu'Awk démarre alors la boucle suivante sans même exécuter le reste du bloc de |
459 |
code. La directive « continue » fonctionne pour tout type de boucle |
460 |
itérative d'Awk, comme le fait la directive « break ». Lorsqu'elle |
461 |
est utilisée à l'intérieur d'une boucle « for », la directive |
462 |
« continue » fait que la variable de contrôle de la boucle est |
463 |
automatiquement incrémentée. Voici un code équivalent pour la boucle : |
464 |
</p> |
465 |
|
466 |
<pre caption="Code équivalent au code précédent"> |
467 |
for ( x=1; x<=21; x++ ) { |
468 |
if ( x == 4 ) { |
469 |
continue |
470 |
} |
471 |
print "iteration",x |
472 |
} |
473 |
</pre> |
474 |
|
475 |
<p> |
476 |
Il n'est pas nécessaire d'incrémenter « x » juste avant l'appel de |
477 |
« continue » comme c'était le cas dans notre boucle |
478 |
« while », puisque la boucle « for » incrémente |
479 |
« x » automatiquement. |
480 |
</p> |
481 |
|
482 |
</body> |
483 |
</section> |
484 |
<section> |
485 |
<title>Tableaux</title> |
486 |
<body> |
487 |
|
488 |
<p> |
489 |
Vous serez ravi d'apprendre qu'Awk a des tableaux. Cependant, sous Awk, il est |
490 |
habituel de démarrer les index de tableau à 1, plutôt que 0 : |
491 |
</p> |
492 |
|
493 |
<pre caption="Exemple de tableaux Awk"> |
494 |
myarray[1]="jim" |
495 |
myarray[2]=456 |
496 |
</pre> |
497 |
|
498 |
<p> |
499 |
Quand Awk rencontre le premier assignement, myarray est créé et l'élement |
500 |
myarray[1] est initialisé à "jim". Après que le second assignement ait été |
501 |
évalué, le tableau a deux éléments. |
502 |
</p> |
503 |
|
504 |
<p> |
505 |
Une fois défini, Awk a un moyen pratique pour parcourir les éléments d'un |
506 |
tableau : |
507 |
</p> |
508 |
|
509 |
<pre caption="Parcourir des tableaux"> |
510 |
for ( x in myarray ) { |
511 |
print myarray[x] |
512 |
} |
513 |
</pre> |
514 |
|
515 |
<p> |
516 |
Ce code affiche chaque élément du tableau myarray. Quand vous utilisez cette |
517 |
forme spéciale du « in » d'une boucle for, Awk assigne chaque index |
518 |
existant de myarray à x (la variable de contrôle de la boucle) à tour de rôle, |
519 |
exécutant le bloc de code de la boucle une fois après chaque assignement. Bien |
520 |
que ce soit une fonctionnalité d'Awk vraiment pratique, il a un |
521 |
inconvénient : quand Awk parcourt les index du tableau, il ne le fait pas |
522 |
suivant un ordre particulier. Cela signifie qu'il n'y a pas de moyen pour nous |
523 |
de savoir si le résultat du code précédent sera : |
524 |
</p> |
525 |
|
526 |
<pre caption="Résultat du code précédent"> |
527 |
jim |
528 |
456 |
529 |
</pre> |
530 |
|
531 |
<p> |
532 |
ou |
533 |
</p> |
534 |
|
535 |
<pre caption="Un autre résultat possible du même code"> |
536 |
456 |
537 |
jim |
538 |
</pre> |
539 |
|
540 |
<p> |
541 |
Pour reprendre une phrase de Forrest Gump, parcourir le contenu d'un tableau |
542 |
est comme une boîte de chocolats : vous ne savez jamais sur quoi vous |
543 |
allez tomber. Cela a quelque chose à voir avec la nature « chaînes de |
544 |
caractères » des tableaux Awk, ce que nous allons voir à présent. |
545 |
</p> |
546 |
|
547 |
</body> |
548 |
</section> |
549 |
<section> |
550 |
<title>Les index de tableaux en « chaînes de caractères »</title> |
551 |
<body> |
552 |
|
553 |
<p> |
554 |
<uri link="/doc/fr/articles/l-awk1.xml">Dans mon article précédent</uri>, je |
555 |
vous ai montré qu'Awk conserve en fait les valeurs numériques en format de |
556 |
chaînes de caractères. Pendant qu'Awk réalise les conversions nécessaires pour |
557 |
faire son travail, il ouvre la porte pour du code un peu étrange : |
558 |
</p> |
559 |
|
560 |
<pre caption="Code un peu étrange"> |
561 |
a="1" |
562 |
b="2" |
563 |
c=a+b+3 |
564 |
</pre> |
565 |
|
566 |
<p> |
567 |
Une fois ce code exécuté, « c » est égal à 6. Puisqu'Awk fonctionne |
568 |
avec des chaînes de caractères, ajouter les chaînes de caractères |
569 |
« 1 » et 2 est fonctionnellement la même chose que d'ajouter les |
570 |
nombres 1 et 2. Dans les deux cas, Awk réalisera correctement l'opération. La |
571 |
nature « chaînes de caractères » est assez intriguante : vous |
572 |
pouvez vous demander si nous utilisons des index de chaînes de caractères pour |
573 |
les tableaux. Par exemple, prenez le code suivant : |
574 |
</p> |
575 |
|
576 |
<pre caption="Exemple de code"> |
577 |
myarr["1"]="Mr. Whipple" |
578 |
print myarr["1"] |
579 |
</pre> |
580 |
|
581 |
<p> |
582 |
Comme vous pouvez vous y attendre, ce code affichera « Mr. Whipple ». |
583 |
Mais que se passe-t-il si nous enlevons les guillemets autour du deuxième index |
584 |
"1" ? |
585 |
</p> |
586 |
|
587 |
<pre caption="En enlevant les guillemets du code"> |
588 |
myarr["1"]="Mr. Whipple" |
589 |
print myarr[1] |
590 |
</pre> |
591 |
|
592 |
|
593 |
<p> |
594 |
Deviner le résultat de cet extrait de code est un peu plus difficile. Est-ce |
595 |
que Awk considère myarr["1"] et myarr[1] comme 2 éléments séparés du tableau, |
596 |
ou référencent-ils le même élément ? La réponse est qu'ils référencent le |
597 |
même élement, Awk affichera « Mr. Whipple » exactement comme dans le |
598 |
premier extrait de code. Bien que cela puisse sembler étrange, derrière le |
599 |
décor, Awk a utilisé des index de chaînes de caractères pour ses tableaux tout |
600 |
le temps ! |
601 |
</p> |
602 |
|
603 |
<p> |
604 |
Après avoir pris connaissance de cette curiosité, certains d'entre nous peuvent |
605 |
être tentés d'exécuter du code farfelu comme ça : |
606 |
</p> |
607 |
|
608 |
<pre caption="Code farfelu"> |
609 |
myarr["name"]="Mr. Whipple" |
610 |
print myarr["name"] |
611 |
</pre> |
612 |
|
613 |
<p> |
614 |
Ce code ne génère pas d'erreur et fonctionne comme nos exemples précédents et |
615 |
affichera aussi "Mr. Whipple" ! Comme vous pouvez le voir, Awk ne nous |
616 |
limite pas à utiliser uniquement que des index de nombres entiers ; nous |
617 |
pouvons utiliser des index de chaînes de caractères si nous le voulons, sans |
618 |
que cela ne crée de problème. Chaque fois que nous utilisons des index de |
619 |
tableau n'étant pas des nombres entiers comme myarr["name"], nous utilisons des |
620 |
tableaux associatifs. Techniquement, Awk ne fait rien de différent quand nous |
621 |
utilisons un index de chaînes de caractères (même si vous utilisez un index de |
622 |
« nombre entier », Awk le traite encore comme une chaîne de |
623 |
caractères). Cependant, vous devriez utiliser ces tableaux associatifs : |
624 |
c'est plutôt cool et impressionnera votre patron. L'astuce d'index de chaînes |
625 |
de caractères sera notre petit secret. ;) |
626 |
</p> |
627 |
|
628 |
</body> |
629 |
</section> |
630 |
<section> |
631 |
<title>Les outils pour les tableaux</title> |
632 |
<body> |
633 |
|
634 |
<p> |
635 |
Quand il en vient aux tableaux, Awk nous donne beaucoup de flexibilité. Nous |
636 |
pouvons utiliser des chaînes de caractères comme index et nous ne sommes pas |
637 |
tenus d'avoir une suite continue de nombres d'index (par exemple, nous pouvons |
638 |
définir myarr[1] et myarr[1000] et laisser les autres éléments indéfinis). Bien |
639 |
que cela puisse être très utile, dans certaines circonstances, cela peut porter |
640 |
à confusion. Heureusement, Awk offre quelques fonctionnalités pratiques pour |
641 |
aider à rendre les tableaux plus facilement manipulables. |
642 |
</p> |
643 |
|
644 |
<p> |
645 |
Tout d'abord, nous pouvons supprimer des éléments d'un tableau. Si vous voulez |
646 |
effacer l'élément 1 de votre tableau fooarray, tapez : |
647 |
</p> |
648 |
|
649 |
<pre caption="Supprimer des éléments du tableau"> |
650 |
delete fooarray[1] |
651 |
</pre> |
652 |
|
653 |
<p> |
654 |
Et si vous voulez voir si un élément particulier du tableau existe, vous pouvez |
655 |
utiliser l'opérateur booléen spécial « in » comme décrit ci-dessous. |
656 |
</p> |
657 |
|
658 |
<pre caption="Vérifier si un élément particulier du tableau existe"> |
659 |
if ( 1 in fooarray ) { |
660 |
print "Oui ! Il est ici." |
661 |
} else { |
662 |
print "Non ! Je ne le trouve pas." |
663 |
} |
664 |
</pre> |
665 |
|
666 |
</body> |
667 |
</section> |
668 |
<section> |
669 |
<title>La prochaine fois</title> |
670 |
<body> |
671 |
|
672 |
<p> |
673 |
Nous avons abordé pas mal de points dans cet article. La prochaine fois, je |
674 |
compléterai votre connaissance d'Awk en vous expliquant comment utiliser les |
675 |
fonctions mathématiques, les fonctions de chaînes de caractères et comment |
676 |
créer vos propres fonctions. Je vous parcourrai la création d'un programme |
677 |
d'équilibrage d'un carnet de chèques. D'ici là, je vous encourage à écrire |
678 |
quelques programmes Awk et de consulter les ressources suivantes. |
679 |
</p> |
680 |
|
681 |
</body> |
682 |
</section> |
683 |
</chapter> |
684 |
|
685 |
<chapter> |
686 |
<title>Ressources</title> |
687 |
<section> |
688 |
<body> |
689 |
|
690 |
<ul> |
691 |
<li> |
692 |
Lisez les autres articles de Daniel sur Awk : Awk par l'exemple, <uri |
693 |
link="l-awk1.xml">Partie 1</uri> <!-- et <uri link="l-awk3.xml">Part |
694 |
3</uri>.--> |
695 |
</li> |
696 |
<li> |
697 |
Si vous recherchez un bon vieux livre, <uri |
698 |
link="http://www.oreilly.com/catalog/sed2/">Sed & Awk, 2nd |
699 |
Edition</uri> d'O'Reilly est un très bon choix. |
700 |
</li> |
701 |
<li> |
702 |
Consultez aussi la <uri |
703 |
link="http://www.faqs.org/faqs/computer-lang/awk/faq/">FAQ comp.lang.awk |
704 |
</uri>. Elle contient beaucoup de liens supplémentaires sur Awk. |
705 |
</li> |
706 |
<li> |
707 |
<uri link="http://sparky.rice.edu/~hartigan/awk.html">Awk tutorial</uri> de |
708 |
Patrick Hartigan est présenté avec des scripts Awk avancés. |
709 |
</li> |
710 |
<li> |
711 |
<uri link="http://www.tasoft.com/tawk.html">Thompson's TAWK Compiler</uri> |
712 |
compile les scripts Awk en exécutables binaires rapides. Des versions sont |
713 |
disponibles pour Windows, OS/2, DOS et UNIX. |
714 |
</li> |
715 |
<li> |
716 |
<uri link="http://www.gnu.org/software/gawk/manual/gawk.html">The GNU Awk |
717 |
User's Guide</uri> est disponible comme référence en ligne. |
718 |
</li> |
719 |
</ul> |
720 |
|
721 |
</body> |
722 |
</section> |
723 |
</chapter> |
724 |
</guide> |