Tuteur pour le langage AWK

novalid      

Texte du Tuteur écrit par Gilles HUNAULT

Consultez aussi la liste des autres tuteurs (langages, logiciels, systèmes d'exploitations...) ...


<-- See also the Gawk Manual and the Effective Awk programming page. -->

Table des Matières

Le langage Awk

      - 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

Une dizaine d'exemples gradués


      # 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

INTRODUCTION

Le langage AWK est prévu pour traiter des fichiers texte. Si Prog.Awk contient le programme, et si on veut traiter le fichier Demo.Txt, on écrit :

         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.

EXEMPLES

Avec le programme

                { 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 12

               
on obtient comme affichage :

                BOBY moyenne 11.5
                ZELYNOU moyenne 8.5
                ANTIN moyenne 6
                BOB moyenne 12
                IZEL moyenne 17


  
De même, avec le programme

           {   print $1
               printf(" moyenne %5.2f\n",($2+$3)/2 )
           } # fin de traitement de la ligne courante

           
et le fichier :

      BOBY                    18 5
      ZELYNOU               6 11
      ANTIN             8 4
      BOB              16 8 15
      IZEL              16 18 12


on obtient comme affichage :

              BOBY
              moyenne  11.50
              ZELYNOU
              moyenne   8.50
              ANTIN
              moyenne   6.50
              BOB
              moyenne  12.00
              IZEL
              moyenne  17.00


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
Les é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).

INSTRUCTIONS

Les instructions classiques sont

          =             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 i

Awk initialise automatiquement les variables. Ainsi { print i+1 } met automatiquement 0 dans i puis affiche 1 .

EXPRESSIONS REGULIERES

AWK est surtout agréable pour son mécanisme de filtrage et ses expressions régulières . Le traitement d'une ligne courante se fait par et { action(s) }, avec comme cas particuliers
         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 éventuelles

EXERCICE 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é

COMPLEMENTS

Certains caractères ne peuvent être utilisés directement dans les exprressions régulières. On met un \ devant. Ainsi, /\\/ désigne les chaines qui contiennent / et /\./ celles qui ont un ..

On peut éxécuter des instructions avant l'ouverture du fichier grâce à BEGIN { } ou après la fermeture du fichier grâce à END { }. Attention : FILENAME n'est pas disponible dans la partie 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 .