- Introduction au langage - Exemple élémentaire de parcours de fichier - Variables et Fonctions - Instructions en Awk - Expressions régulières et filtrage - Exercice de révision - Compléments sur Awk - Un exemple difficile en Awk sous Dos et sous Unix
# Xmp1.Awk : numérotation des lignes d'un fichier # Xmp2.Awk : numérotation cadrée des lignes d'un fichier # Xmp3.Awk : détection simple de chaine # Xmp4.Awk : détection par expression régulière # Xmp5.Awk : un bonjour amélioré # Xmp6.Awk : table de multiplication # Xmp7.Awk : moyenne de classe # Xmp8.Awk : un petit dictionnaire # Xmp9.Awk : gestion de répertoire
AWK -fPROG.AWK DEMO.TXT.Il y a ouverture du fichier, parcours ligne par ligne et action éventuelle, puis fermeture du fichier. La ligne courante a pour nom fixé $0 ; elle contient NF mots ; le ième mot s'appelle $i . L'affichage se fait par print ou printf (f pour formatté).
Le traitement de chaque ligne se fait entre accolades { et } . On délimite les instructions par un ; . Les commentaires commencent par # ; on distingue majuscule et minuscule.
La syntaxe de base est la même que celle du langage C, sauf qu'on ne déclare pas les variables.
{ print $1 " moyenne " ($2 +$3)/2 }et le fichier :
BOBY 18 5 ZELYNOU 6 11 ANTIN 8 4 BOB 16 8 15 IZEL 16 18 12on obtient comme affichage :
BOBY moyenne 11.5 ZELYNOU moyenne 8.5 ANTIN moyenne 6 BOB moyenne 12 IZEL moyenne 17De même, avec le programme
{ print $1 printf(" moyenne %5.2f\n",($2+$3)/2 ) } # fin de traitement de la ligne couranteet le fichier :
BOBY 18 5 ZELYNOU 6 11 ANTIN 8 4 BOB 16 8 15 IZEL 16 18 12on obtient comme affichage :
BOBY moyenne 11.50 ZELYNOU moyenne 8.50 ANTIN moyenne 6.50 BOB moyenne 12.00 IZEL moyenne 17.00Les éléments de tableaux se notent entre crochets. Ainsi T[i] désigne l'élément en position i (i peut être numérique ou caractère).VARIABLES ET FONCTIONS
Awk met à la disposition du programmeur des variables NR numéro global de l'enregistrement FNR numéro local de l'enregistrement FILENAME nom du fichier ouvert ARGV vecteur des arguments passés et des fonctions length(H) donne la longueur de H substr(C,D,F) renvoie F caractères de C à partir de D index(T,C) donne la position de C dans T ou 0 system(D) exécute la commande dos D close(F) ferme la fichier F gsub(R,S,T) remplace R par S dans T
= affectation if conditionnelle for boucle pour while boucle tant que ++ incrémentation de 1 += incrémentation variable exemple : while( i*i < n ) { i++ } for (i=a;i<=b;i+=2) { if (i*i==n) { print "trouvé" } else { print i n i*i } } # finpour iAwk initialise automatiquement les variables. Ainsi { print i+1 } met automatiquement 0 dans i puis affiche 1 .
pas de filtrage, on traite toutes les lignes : { instruction(s) } pas d'action, on affiche la ligne en cours. filtrage <==> filtrage { print $0 } <==> filtrage { print }Le filtrage se réalise par
/ [expression régulière] / / [expression régulière] / ~ [nom de variable] ( condition ) .Une expression régulière est une chaîne de caractère définie par des caractères, des répétititions de caractères ou des positions de caractères. Après les caractères, on peut mettre
* pour indiquer la répétition 0 fois ou plus + pour indiquer la répétition 1 fois ou plus ? pour indiquer la répétition 0 fois ou 1 fois Ainsi A*B correspond à B ou AB ou AAB ou AAAB etc. 0+,?1 correspond à 01 ou à 0,1 ou à 001 ou à 00,1 etc. On dispose aussi des symboles : [] pour grouper des éléments ^ pour indiquer le début de chaîne $ pour indiquer la fin de chaîne | pour indiquer un choix possible . pour indiquer n'importe quel caractère (le "vrai" point se note \.) Quelques expressions régulières simples : ^B G$ ^.$ [AEIOU] ^[ABC] ^[^a-z]$ Quelques expressions Et leur signification : régulières simples : ^B chaîne qui commence par B G$ chaîne qui finit par G ^.$ chaîne à un seul caractère [AEIOU] chaîne avec une seule voyelle majusucle ^[ABC] chaîne qui commence par A ou B ou C ^[^a-z]$ chaîne à un seul caractère qui n'est pas une minuscule Quelques expressions régulières techniques : ^[0-9]+$ chaîne non nulle avec seulement des chiffres ^(\+|-)?[O-9]+\.?[0-9]*$ nombre réel avec signe éventuel, point éventuel et décimales éventuellesEXERCICE DE REVISION
Avec le programme /.*A.*I/ /9/ { print $3 ; n++ } /^[a-z]/ { print n ; print " oui ! " } et le le fichier : BOBY 18 5 zelynou 6 11 ANTIN 8 9 Bob 16 9 15 izel 16 18 12 on obtient comme affichage : # une ligne vide oui ! ANTIN 8 9 9 9 2 oui ! # le o de oui est décalé
On peut éxécuter des instructions avant l'ouverture du fichier
grâce à BEGIN {
SI on lance un programme AWK sur plusieurs fichiers, par exemple
par AWK -fProg.AWk *.PAS, NR est le numéro de ligne comme si tous les
fichiers étaient concaténés, FNR est le numéro de ligne pour le
seul fichier en cours.
Pour les tableaux par, le fait de donner un indice crée cet indice. Le
tableau est automatiquement trié par ordre croissant d'indice, qu'il
soit numérique ou chaine. On extrait les indices par la boucle
for .. in.
UN EXEMPLE DIFFICILE
Appliqué au fichier TMP.TXT suivant (généré sous Dos par DIR > TMP.TXT)
Répertoire de G:\
AUTOEXEC BAT 236 8-09-91 11:37p
CONFIG SYS 254 7-27-91 8:35a
ESSAI AWK 648 4-13-90 11:40a
S 647 8-11-91 1:47p
STATDIR AWK 648 4-13-90 11:40a
5 Fichiers 776192 octets disponibles
le programme /-/ && $1 !~ /^\./ { if (NF < 5) { $3 = $2 ; $2 = "???" }
tot[$2] += $3 ; nb[$2] ++ }
END { for (ext in tot) printf ("%-3s %3d %8d\n" ,
ext , nb[ext] , tot[ext] ) }
affiche
??? 1 647
AWK 2 1296
BAT 1 236
SYS 1 254
Sous Unix, le même exercice donne
# Xmp9.Awk : gestion de r‚éperoire
BEGIN { fs="DIR.DIR" ; system("ls -al > " fs) ; close(fs) ; nbf = 0
for (iar=1;iar<=ARGC;iar++) { ARGV[iar]= "" }; ARGV[1] = fs }
/-/ && $1 !~ /^d/ && $9 != "DIR.DIR" {
ip = index($9,".")
if (ip > 0) { ext = substr($9,1+ip) } else { ext = "???" }
tot[ext] += $5 ; nb[ext] ++ ; nbf++}
END { print " ext nb_fich cumul_taille"
for (ext in tot)
printf ("%-15s %3d %12d\n" , ext , nb[ext] , tot[ext] )
system("rm " fs)
if (nbf==0) { print " mais je n'ai vu aucun fichier !! "}
}
Cliquez ici pour une dizaine d'exemples gradués
Il est possible de récupérer le manuel de référence pour Gawk
ici
et une version sans doute plus récente
là.