Système UNIX : Programme awk
Retour à la page d'accueil
Retour à l'index du tutoriel sur le système UNIX
 

Le programme awk

Le programme awk explore un ou plusieurs fichiers d'entrée à la recherche d'arrangements et il exécute des actions sur les enregistrements (lignes) comportant ces arrangements. Ces arrangements et actions sont enchâssés dans un programme. Les arrangements-actions ont la forme :

arrangement { action(s) }

Le programme peut être simple et figurer sur la ligne de commande ou, s'il est plus complexe, il peut avoir été enregistré dans un fichier.

Le nom de awk provient de la première lettre du nom de famille de ses trois concepteurs.

Utilisation

Considérons, à titre d'exemple, le fichier de données exemple.txt :

helene   56  edu  hcyr@sun.com
jean     32  ri   jeanc@inexpress.net
julie    22  adm  juliem@sympatico.ca
michel   24  inf  michel@uqo.ca
richard  25  inf  rcaron@videotron.ca

La commande awk suivante exécutée sur le fichier ci-dessus affiche le premier champ. Comme aucun arrangement n'a été spécifié, l'action { print $1 } s'applique à tous les enregistrements du fichier :

station% awk '{ print $1 }' exemple.txt
helene
jean
julie
michel
richard

Les champs du programme awk sont en effet appelés $1, $2, $3, etc et $0 pour la ligne entière. Notez aussi la présence d'apostrophes pour cadrer le programme en argument afin de le protéger de toute interprétation que pourrait faire le shell de certains caractères spéciaux.

L'arrangement NR > 1 pourrait être spécifié pour sauter le premier enregistrement, NR représentant le numéro de l'enregistrement (« Number of the Record ») :

station% awk 'NR > 1 { print $1 }' exemple.txt
jean
julie
michel
richard

Le programme awk pourrait aussi afficher les deux premiers champs (champ 2, puis champ 1) et comporter une comparaison pour limiter la sélection aux seuls enregistrements dont le second champ est supérieur à 24 :

station% awk '{ if ($2 > 24) print $2, $1 }' exemple.txt
56 helene
32 jean
25 richard

Nous aurions pu obtenir le même résultat en spécifiant l'arrangement $2 > 24, au lieu d'inclure la commande if :

station% awk '$2 > 24 { print $2, $1 }' exemple.txt
56 helene
32 jean
25 richard

Au lieu de la commande print, nous pourrions utiliser la commande printf qui permet le formatage. Elle fonctionne comme son éguivalent dans le langage C. Les masques de formatage de la commande printf %-10s et %6d signifient respectivement d'afficher une chaîne de caractères sur 10 colonnes et de la justifier à gauche, puis d'afficher un champ numérique sur 6 colonnes (justifié à droite par défaut) :

station% awk '{ if ($2 > 24) printf ("%-10s %6d\n", $1, $2) }' exemple.txt
helene         56
jean           32
richard        25

Nous pouvons ajouter un titre à notre liste en utilisant l'arrangement BEGIN (mot réservé) pour lequel l'action s'applique avant la lecture des enregistrements (la commande awk de cet exemple a été decomposée en plusieurs lignes ici afin de mieux l'illustrer, mais elle doit être entrée sur une même ligne) :

station% awk 'BEGIN { printf ("Nom        Numéro\n---------- ------\n") }
                 NR >= 1 { if ($2 > 24) { printf ("%-10s %6d\n", $1, $2) } }'
                exemple.txt
Nom        Numéro
---------- ------
helene         56
jean           32
richard        25

Il ne reste plus qu'à faire le total des valeurs contenues dans le second champ et de les afficher à la fin. L'arrangement END (mot réservé) s'applique à la fin de la lecture de tous les enregistrements (la commande awk de cet exemple a été decomposée en plusieurs lignes ici afin de mieux l'illustrer, mais elle doit être entrée sur une même ligne) :

station% awk 'BEGIN { printf ("Nom        Numéro\n---------- ------\n");
                         total = 0; }
                 NR >= 1 { if ($2 > 24) { printf ("%-10s %6d\n", $1, $2);
                           total += $2 } }
                 END { printf ("           ------\n           %6d\n", total) }'
                exemple.txt
Nom        Numéro
---------- ------
helene         56
jean           32
richard        25
           ------
              113

Le programme de awk, devenu un peu long, peut être enregistré dans un fichier et son nom passé en paramètre en utilisant l'option -f. Si le programme est enregistré dans fichier liste.awk comme suit :

BEGIN   {
        printf ("Nom        Numéro\n---------- ------\n");
        total = 0;
        }
NR >= 1 {
        if ($2 > 24)
           {
           printf ("%-10s %6d\n", $1, $2);
           total += $2
           }
        }
END     {
        printf ("           ------\n           %6d\n", total)
        }

Alors, la commande awk suivante faisant appel à ce fichier produirait le même résultat :

station% awk -f liste.awk exemple.txt
Nom        Numéro
---------- ------
helene         56
jean           32
richard        25
           ------
              113

Autres options du programme awk

Il existe dans le système UNIX plusieurs fichiers dont les champs contiennent des blancs et que ces champs doivent être délimités par un caractère autre que le blanc, comme le deux-points (:) (par exemple le fichier passwd). Il en est de même des données produites par le programme grep.

Il est possible de dire à awk d'utiliser un autre caractère pour délimiter les champs, ceci en utilisant l'option -F. Ainsi, si notre fichier exemple.txt d'origine pourrait être ainsi constitué :

helene:56:edu:hcyr@sun.com
jean:32:ri:jeanc@inexpress.net
julie:22:adm:juliem@sympatico.ca
michel:24:inf:michel@uqo.ca
richard:25:inf:rcaron@videotron.ca

Il serait possible de le traiter avec le même programme awk, tout en spécifiant l'option -F:, pour lui indiquer que le délimiteur des champs est le deux-points (:) :

station% awk -F: -f liste.awk exemple.txt
Nom        Numéro
---------- ------
helene         56
jean           32
richard        25
           ------
              113

Et, bien sûr, la casse a son importance; il ne faut pas confondre les options -F et -f.

Le langage de awk comporte les instructions suivantes :

if ( condition ) instruction [ else instruction ]
while ( condition ) instruction
for (expression ; condition ; expression ) instruction
break
continue
{ [ instruction ] }
variable = expression
print [ liste-d´expressions ] [ >fichier ]
next   (saute les arrangements résiduels de cet enregistrement)
exit   (saute le reste des enregistrements)

Les expressions sont des entiers ou des chaînes de caractères et sont assemblées par les opérateurs +, -, *, /, % et la concatenation (une espace). Les opérateurs de C++ --, +=, -=, *=, /= et %= sont également valides.

Les variables peuvent être des scalaires, des tableaux (notation a[i]) ou des champs ($1, $2, etc.). Les constantes de chaînes de caractères sont délimités par des guillemets (").

La fonction length donne la longueur de l'argument qui lui est présenté ou de toute la ligne s'il n'y a pas d'argument.

Si l'on omet le nom du fichier, awk agit sur le fichier d'entrée stdin.

Le programme awk est très utile dans les pipes.

Pour plus d'information sur la commande awk, lancez man awk.


Programme grep Programme find