L'utilitaire AWK

Introduction

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 enchassés dans un programme.

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

Ce programme est particulièrement utile pour récupérer des informations, générer des rapports, transformer des données entre autres.

Utilisation du programme AWK

Syntaxe

La syntaxe de AWK est la suivante :

awk [-F] [-v var=valeur] "programme" <fichier>

ou

awk [-F] [-v var=valeur] -f <fichier_config_awk> <fichier>

L'argument -F permet d'indiquer le séparateur de champ (-F : pour indiquer que : est le séparateur de champ).

L'argument -v permet de définir une variable qui sera utilisée dans la suite du programme.

Un programme awk possède la structure suivante : critères de sélection d'une chaîne {action}.

Lorsqu'il n'y a pas de critère, l'action s'applique à toutes les lignes du fichier.

Exemple :

awk -F ":" '{print  $NF}' /etc/passwd

Dans cet exemple, cette action s'applique à toutes les lignes du fichier /etc/passwd. L'action consiste à afficher le nombre de champs dans le fichier. NF est une variable prédéfinie d'awk. Dans ce fichier, les champs sont séparés par :.

Dans un enregistrement, les champs sont référencés par $1, $2, ..., $NF.

Exemple :

awk -F ":" '{print  $1,$6}' /etc/passwd

Il existe plusieurs variétés d'awk en fonction des systèmes UNIX, certaines fonctions ou variables systèmes ne sont pas toutes disponibles en fonction du système. Des différences sensibles de comportement peuvent apparaître que l'on soit sous HP-UX, Solaris ou Linux.

Critères de sélection

Présentation

Un critère peut être une expression régulière, une expression ayant une valeur chaine de caractères, une expression arithmétique, une combinaison des expressions précédentes.

Le critère est inséré entre les chaines BEGIN et END, avec la syntaxe ci-dessous :

awk -F ":" 'BEGIN{instructions} criteres END{instructions}' <fichier>

BEGIN peut être suivi d'instructions comme une ligne de commentaire ou pour définir le séparateur.

Exemple :         

BEGIN {print "Verification du fichier" ; FS=":"}

De même pour END :

END {print "Verification terminee"}

Les mots clés BEGIN et END sont optionnels.

Les expressions régulières

L'utilisation des expressions régulières avec AWK est très courante. Les syntaxes sont résumées ci-après.

Syntaxe n°1 :

/expression régulière/ {instructions}
$0     /expression régulière/ {instructions}

Les instructions sont exécutées pour chaque ligne contenant une chaîne satisfaisant à l'expression régulière.

Syntaxe n°2 :

expression    /expression régulière/ {instructions}

Les instructions sont exécutées pour chaque ligne où la valeur chaîne de l'expression contient une chaîne satisfaisant à l'expression régulière.

Syntaxe n°3 :

expression    !/expression régulière/ {instructions}

Les instructions sont exécutées pour chaque ligne où la valeur chaîne de l'expression ne contient pas une chaîne satisfaisant à l'expression régulière.

Exemple :

BEGIN { print "Verification des champs 2 et 3"; FS="|"} 
$2 ! /^[0-9][0-9]*$/ { print "Erreur sur champ2, ligne n°"NR": \n"$0}
$3 ! /^[0-9][0-9]*$/ { print "Erreur sur champ3, ligne n°"NR": \n"$0} 
END { print "Verification effectuee"}

Les expressions relationnelles

Un critère peut contenir des opérateurs de comparaison ( <, <=, ==, !=, >=, >).

Exemple :

BEGIN { print "On cherche lignes dont champ 4 est superieur a 30"; FS="|"}
$4 > 30 { print "Critere rempli a la ligne n°"NR": \n"$0}
END { print "Verification terminee"}

Combinaison de critères

Un critère peut être constitué par une combinaison booléenne avec les opérateurs OU ( || ) et ET ( && ).

Exemple :

BEGIN { print "Recherche de la ligne avec chaine1 dans le champ 1 ou avec le champ 4 inferieur a 30"; FS="|"}
$1 == "chaine1" || $4 < 30 { print "Ligne repondant au critere ligne n°"NR": \n"$0}
END { print "Verification terminee"}

Actions

Présentation

Les actions permettent de transformer ou de manipuler les données, elles contiennent une ou plusieurs instructions. Les actions peuvent être de différents types : fonctions prédéfinies, fonctions de contrôles, fonctions d'affectation, fonctions d'affichage.

Fonctions prédéfinies traitant des numériques

Fonction Description
atan2(y,x) Arctangente de x/y en radians (entre -pi et pi)
cos(x) Cosinus (radian)
exp(x) Exponentielle
int(x) Partie entière
log(x) Logarithme naturel
rand(x) Nombre aléatoire (entre 0 et 1)
sin(x) Sinux (radian)
sqrt(x) Racine carré
srand(x) Valeur de départ pour générer un nombre aléatoire

Fonctions prédéfinies traitant des chaines de caractères

Ci-après les fonctions les plus courantes pour le traitement des chaînes de caractères dans les systèmes UNIX :

Fonction Description
gsub(expression-régulière, nouvelle-chaine,chaine-de-caractères) Dans chaine-de-caractères tous les caractères décrits par l'expression régulière sont remplacés par nouvelle-chaine. gsub et équivalent à gensub. Exemple :
gsub(/a/,"ai","oi")
remplace la chaine oi par ai
index(chaine-de-caractères, caractère-à-rechercher)

Donne la première occurence du caractère-à-rechercher dans la chaine chaine-de-caractères.

Exemple :
index("chaine1","i")  
length(chaine-de-caractères) Renvoie la longueur d'une chaine de caractères
match(chaine-de-caractères, expression-régulière)

Renvoie l'indice de la position de la chaîne chaine-de-caractères respectant l'expression régulière. Exemple :

match("PO1235D",/[0-9][0-9]/)  
retourne  n=3.
printf(format,valeur) Permet d'envoyer des affichages (sorties) formatées, la syntaxe est identique de la même fonction en C Exemple :
printf("La variable i est égale à %7,2f",i) 
sortie du chiffre i avec 7 caractères (éventuellement caractères vides devant) et 2 chiffres après la virgule. Exemple :
printf("La ligne est %s",$0) > "fichier.int" 
Redirection de la sortie vers un fichier avec >, on peut utiliser aussi la redirection >>. Veiller à ne pas oublier les double quotes autour du nom du fichier.
split(chaine-de-caractères,tableau,séparateur) Scinde la chaîne chaine-de-caractères dans un tableau, le séparateur de champ est le troisième argument. Exemple :
split("essai de chaine", tab, " ")
retourne  tab[1]="essai" tab[2]="de" tab[3]="chaine"
sprintf(format,valeur) printf permet d'afficher à l'écran alors que sprintf renvoie la sortie vers une chaîne de caractères. Exemple :
machaine=sprintf("Valeur de i %d ",i) 
retourne machaine="Valeur de i 3" (si i=3)
substr(chaine-de-caractères,pos,long)

Extrait une chaine de longueur long dans la chaîne chaine-de-caractères à partir de la position pos et l'affecte à une chaîne.

system(chaine-de-caractères) Permet de lancer des commandes d'autres programmes Exemple :
commande=sprintf("ls | grep chaine1") 
Exécution de la commande UNIX "ls | grep chaine1" system(commande)
tolower(chaine-de-caracteres) Retourne la chaîne de caractères convertie en minuscules
toupper(chaine-de-caracteres) Retourne la chaîne de caractères convertie en majuscules

Exemple :

cat ${FIC_NOM} | awk -vdate_sys=${date_entree} \
   '{printf(";%d;%s;%s;20%s;%s;%s;%d;%s;20%s;20%s;%s;%s;MT;P;%s;;N;6;;\n",  \
    substr($0,1,12), substr($0,13,5), \
    substr($0,18,11), substr($0,29,6), \
    substr($0,35,2), substr($0,37,30), \
    substr($0,67,19)/100000, substr($0,86,3), substr($0,89,6), substr($0,95,6),substr($0,101,5),substr($0,106,12),date_sys )}'

$0 dans cet exemple est l'enregistrement (une ligne).

Fonctions utilisateur

Il est possible de définir une fonction utilisateur afin qu'elle soit considérée comme une fonction prédéfinie.

Exemple :     

function fonction(liste des paramètres)
    {
          instructions
          return valeur
    }

Les variables et opérations sur les variables

Présentation

Il existe les variables système et utilisateur. Les variables systèmes non modifiables donnent des informations sur le déroulement du programme.

Les variables utilisateur

Il n'est pas nécessaire d'initialiser une variable, par défaut, si c'est un numérique, elle est égale à 0, si c'est une chaîne, elle est égale à une chaîne vide.

Une variable peut contenir du texte, puis un chiffre, en fonction de son utilisation awk détermine le type (numérique ou chaine)

Les variables prédéfinies par AWK

Les variables prédéfinies sont résumées ci-après :

Variable Description
ARGC Nombre d'arguments de la ligne de commande
ARGIND Index du tableau ARGV du fichier courant
ARGV Tableau des arguments de la ligne de commande
CONVFMT Format de conversion pour les nombres
ENVIRON Tableau contenant les valeurs de l'environnement courant
ERRNO Contient une chaine décrivant une erreur
FIELIWIDTHS Variable expérimentale à éviter d'utiliser
FILENAME Nom du fichier d'entrée
FNR Numéro d'enregistrement dans le fichier courant
FS Contrôle le séparateur des champs d'entrée
IGNORECASE Contrôle les expressions régulières et les opérations sur les chaînes de caractères
NF Nombre de champs dans l'enregistrement courant
NR Nombre d'enregistrements lus
OFMT Format de sortie des nombres
OFS Séparateur des champs de sortie
ORS Séparateur des enregistrements de sortie
RLENGTH Longueur de la chaîne sélectionnée par le critère "\ n"
RS Contrôle le séparateur des enregistrements d'entrée "\ n"
RSTART Début de la chaîne sélectionnée par le critère
SUBSEP Séparateur d'indiçage

Opérations sur les variables

Il est possible de manipuler les variables et d'effectuer des opérations dessus. Les différents opérateurs sont les opérateurs arithmétiques classiques (+, -, *, /, %(modulo, reste de la division), (puissance)) et les opérateurs d'affectation (=, +=, -=, *=, /=, %=, =).

var=30 affectation du nombre 30 à var
var="chaine1"  affectation de la chaine chaine1 à var
var="chaine1" "chaine2"  concaténation des chaines de caractères chaine1 et chaine2
var=var-valeur        var-=valeur expressions équivalentes
var=var+valeur       var+=valeur expressions équivalentes
var=var*valeur       var*=valeur expressions équivalentes
var=var/valeur        var/=valeur  expressions équivalentes
var=var%valeur      var%=valeur  expressions équivalentes
var=var+1               var++ expressions équivalentes
var=var-1                var--   expressions équivalentes

Les variables de champ

Les champs d'un enregistrement (ligne) sont désignés par $1, $2,..., $NF (dernier champ d'une ligne).

L'enregistrement complet (ou ligne) est désigné par $0.

Une variable champ a les mêmes propriétés que les autres variables.

Exemple :

i=3
print ($i + 1)

dans l'exemple, le champ 4 est affiché.

Lorsque $0 est modifié, les variables des champs $1, ..., $NF sont redéfinies.

Quand l'une des variables de champ est modifiée, $0 est modifié. ATTENTION : le séparateur de champ n'est pas celui défini par FS mais celui défini par OFS (output field separator).

Les structures de contrôle

Présentation

Les structures de contrôle disponibles avec awk sont :

  • les décisions (if else) ;
  • les boucles (while, for, do while, loop) ;
  • les sauts (next, exit, continue, break)

Les décisions (if else)

Syntaxe :

if (condition) vraie
        instruction1
      else
        instruction2

Exemple 1 :

awk '{ if ($2 > 4) print $2,$1}' <fichier>

Ou

awk '$2 > 4 { print $2,$1 }' <fichier>

Exemple 2 : Test d'un champ vide

BEGIN{print "Test du champ 2 vide" ;FS=":"}
     NF==7 {       # pour toutes les lignes comportant 7 champs
     If ($2=="")   # Si le deuxième champ est vide
            { print "Champ2 vide" }
     else          # Dans le cas contraire
            { print "Champ2 renseigne" }
     END{print "Fin du traitement"}

Les boucles (while, for, do while)

Syntaxes :

while (condition) vraie
            instruction

for(instruction depart ;condition ;incrémentation)
            do {instructions}
                   
while (condition)

Exemple while : Affichage de tous les champs d'une ligne

BEGIN{print "Demarrage du traitement du fichier" ;FS="|"}
    { i=1                # Initialisation du compteur
     while ( i =< NF)     # Tant que la fin de ligne n'est pas atteinte
      {  print $i
        $i++ 
      }
    }
  END{print "Fin du traitement"}

Exemple for : Affichage de tous les champs d'une ligne

BEGIN{print "Debut du traitement" ;FS=":"}
   for (i=1 ;i<=NF ;i++)
      { print $i }
END{print "Fin du traitement"}

Les sauts contrôlés (break, continue, next, exit)

  • break : sortie classiqueent d'une boucle. Alors que break sort d'une boucle, continue force un nouveau passage dans une boucle.
  • next : interrompt le traitement d'une ligne courante et passe à la ligne suivante.
  • exit : abandonne le programme awk, les instructions END sont exécutées.