"Awk est le plus souvent utilisé pour la production de fichiers textes aux spécifications particulières (échanges entre différents systèmes d'informations hétérogènes). Il est aussi utilisé comme analyseur (parser) de fichiers XML ou de fichiers textes pour générer des commandes SQL à partir des données extraites. Il peut être utilisé enfin pour des opérations de calculs complexes et mise en forme de données brutes pour faire des tableaux statistiques...
Il agit comme un filtre programmable prenant une série de lignes en entrée (sous forme de fichiers ou directement via l'entrée standard) et écrivant sur la sortie standard, qui peut être redirigée vers un autre fichier ou programme. Un programme Awk est composé de trois blocs distincts utilisables ou non pour le traitement d'un fichier (prétraitement, traitement, post-traitement). Awk lit l'entrée ligne par ligne, puis sélectionne (ou non) les lignes à traiter par des expressions rationnelles (et éventuellement des numéros de lignes). Une fois la ligne sélectionnée, elle est découpée en champs selon un séparateur d'entrée indiqué dans le programme awk par le symbole FS (qui par défaut correspond au caractère espace ou tabulation). Puis les différents champs sont disponibles dans des variables : $1 (premier champ), $2 (deuxième champ), $3 (troisième champ), …, $NF (dernier champ)." issue de Wikipédia.
La syntaxe est la suivante :
awk [options] [programme] [fichiers]
Ci-dessous la liste des options les plus populaires
-F séparateur | Modification du séparateur de champs |
-f fichier | Lecture du programme à partir d'un fichier |
-v awkVar=$shellVar | Intégration des variables du shell dans le code awk |
Le programme peut avoir plusieurs structures, un mode inline et un mode plus structuré pour pouvoir réaliser des actions plus complexes de manière plus lisibles.
Mais avant toute chose, des variables spéciales peuvent être utilisées dans la partie programme. Voyons quelles sont-elles :
Ces variables sont interprétées au lancement de awk.
Nom de la variable | Valeur par défaut | Rôle de la variable |
---|---|---|
RS | Newline (\n) | Record Separator : Caractère séparateur d'enregistrement (lignes). |
FS | Suite d'espaces et/ou de tabulations | Field Separator : Caractères séparateurs de champs. |
OFS | Espace | Output Field Separator : Séparateur de champ utilisé pour l'affichage. |
ORS | Newline (\n) | Output Record Separator : Caractère séparateur d'enregistrement en sortie. |
ARGV | - | Tableau initialisé contenant les arguments de la ligne de commande (options et nom du script awk exclus). |
ARGC | - | Nombre d'éléments contenus dans le tableau ARGV. |
ENVIRON | Variables d'environnement exportées par le shell. | Tableau contenant les variables d'environnement du shell. |
Ci-dessous le tableau principal contenant la liste des principales variables.
Nom de la variable | Valeur de la variable |
---|---|
$0 | Valeur de l'enregistrement courant |
NF | Number of Field : Nombre de champs de l'enregistrement courant $0. |
$1, $2, ... $NF | $1 contient la valeur du 1er champ, $2 la valeur du 2ème champ etc ... et $NF la valeur du dernier champ. |
NR | Number : Indice de l'enregistrement courant (NR vaut 1 quand la 1ère ligne est en cours de traitement, puis s'incrémente dès que awk change d'enregistrement). |
FNR | File Number : Indice de l'enregistrement courant relatif au fichier en cours de traitement. |
FILENAME | Nom du fichier en cours de traitement. |
RLENGTH | Longueur de la chaîne de caractère trouvée par la fonction match() |
RSTART | Première position de la chaîne de caractère trouvée par la fonction match() |
Exemple simple :
ps -aux | awk '{print $1,$11}'
Sortira automatiquement la première et la 11ème colonne issue de la commande ps.
ps -aux | awk '{print "Utilisateur : " , $1, "\tCommande : " , $11}'
Sortira automatiquement la première et la 11ème colonne issue de la commande ps formatée.
L'exemple suivant utilise l'option "-F" qui permet de définir le délimiteur, ici ":" :
cat /etc/passwd | awk -F : '{print $1,$6}'
On a vu précédemment que $0 affichait la ligne entièrement. si on laisse print sans aucun argument, alors la ligne sera affichée entièrement également :
cat /etc/passwd | awk -F : '{print}'
Cet exemple affichera toute les lignes du fichier sans distinction.
Il est possible de filtrer avec awk. Le critère peut être une expression d'opérateurs et renvoyant la valeur vrai ou faux.
Ci-dessous les opérateurs de tests courants :
Opérateur | Signification |
---|---|
< | Inférieur |
> | Supérieur |
<= | Inférieur ou égal |
>= | Supérieur ou égal |
== | Test d'égalité |
!= | Test d'inégalité |
~ | Correspondance avec une expression régulière |
!~ | Non-correspondance avec une expression régulière |
! | Négation |
&& | Et logique |
|| | Ou logique |
(expression) | Regroupement |
Quelques exemples :
# Aucun filtre mais affiche tout le fichier
awk '/MOTIF/ {print}' fic.txt
# Aucun filtre mais affiche tout le fichier
awk -F':' '/MOTIF/ {print}' fic.txt
# Afficher uniquement les lignes dont le 6eme champ commence par MOTIF
$ awk -F':' '$6 ~ /^MOTIF/ {print}' fic.txt
# Afficher uniquement les lignes dont le 6eme champ NE commence PAS par MOTIF
$ awk -F':' '$6 !~ /^MOTIF/ {print}' fic.txt
# Afficher uniquement les lignes paires
awk -F':' 'NR%2==0 {print $0}' fic.txt
# Afficher les champs 1 et 4 des lignes 4 et 8 du fichier fic.txt
$ awk -F':' 'NR == 4 || NR == 8 {print $1,":",$4}' fic.txt
# Afficher les champs 1 et 7 des lignes 4 à 8 du fichier fic.txt
awk -F':' 'NR == 4 , NR == 8 {print $1,"==>",$7}' fic.txt
# Afficher les champs en ordre inverse
echo "a b c d e f" | awk '{for (i=NF; i>0; i--) {printf("%s ",$i)}}'
# Afficher les champs en ordre inverse en ajoutant un saut de ligne à fin
echo "a b c d e f" | awk '{for (i=NF; i>0; i--) {printf("%s ",$i)} printf "\n"}'
# Utilisation de variable
var="hello"
awk -v x="$var" 'BEGIN {print x}'
# Output : hello
Autres exemples utiles (Wikipédia) :
awk '{print $0}' fichier : affiche toutes les lignes de fichier (idem que cat fichier).
awk '/2/ {print $0}' fichier : affiche toutes les lignes où le caractère 2 est présent (idem que grep '2' ref.txt).
awk '$1~/2/ {print $0}' fichier : affiche toutes les lignes où le caractère 2 est présent dans le premier champ.
awk '{print NR ":", $0}' fichier : affiche le contenu du fichier, mais chaque ligne est précédée de son numéro.
awk -F: '{print $1}' /etc/passwd : renvoie la liste des utilisateurs (idem cut -d : -f 1 /etc/passwd).
awk '/Motif1/ , /Motif2/' fichier : écrit toutes les lignes contenues dans le fichier entre le Motif1 et le Motif2.
Il est possible pour des usages plus complexes d’utiliser awk de manière plus structuré via les mots clés BEGIN et END.
$ cat fichier.awk
BEGIN {
print "Démarrage du programme"
}
{
print "Pas de critères. Donc ce message s'affiche autant de fois qu'il y a d'enregistrement"
}
END {
print "Fin du programme"
}
Pour exécuter ce script, exécuter la commande suivante :
awk -f fichier.awk /etc/passwd
Vous verrez alors ceci :
Démarrage du programme
Pas de critères. Donc ce message s'affiche autant de fois qu'il y a d'enregistrement
Pas de critères. Donc ce message s'affiche autant de fois qu'il y a d'enregistrement
Pas de critères. Donc ce message s'affiche autant de fois qu'il y a d'enregistrement
Pas de critères. Donc ce message s'affiche autant de fois qu'il y a d'enregistrement
Pas de critères. Donc ce message s'affiche autant de fois qu'il y a d'enregistrement
......
Pas de critères. Donc ce message s'affiche autant de fois qu'il y a d'enregistrement
Pas de critères. Donc ce message s'affiche autant de fois qu'il y a d'enregistrement
Pas de critères. Donc ce message s'affiche autant de fois qu'il y a d'enregistrement
Pas de critères. Donc ce message s'affiche autant de fois qu'il y a d'enregistrement
Pas de critères. Donc ce message s'affiche autant de fois qu'il y a d'enregistrement
Fin du programme
On peut changer le script de la manière suivante :
BEGIN {
print "Analyse du fichier /etc/passwd"
FS=":" # Changement du séparateur de champ
}
{
print "User : " $1
print "Home : " $6
print ""
}
END {
print "Fin d'analyse du fichier /etc/passwd"
}
Pour exécuter ce script, exécuter la commande suivante :
awk -f fichier.awk /etc/passwd
Vous verrez alors ceci :
User : root
Home : /root
User : daemon
Home : /usr/sbin
User : bin
Home : /bin
User : sys
Home : /dev
User : sync
Home : /bin
User : games
Home : /usr/games
Il est possible de rajouter des conditions et d'afficher le résultat via la fonction print. Un exemple issue du site https://www.quennec.fr/book/export/html/429 .
$ cat infoproc.awk
BEGIN{
RS="\n\n" # Separateur d'enregistrement
FS="\n" # Separateur de ligne
# En-tete et debut de page HTML
print "<html>"
print "<head>"
print "<title>Informations CPU et mémoire</title>"
print "<style type=\"text/css\">"
print "table {border: solid thin; padding 10px; margin 5px}"
print "table.proc {color: DarkSlateBlue; border-color: DarkSlateBlue}"
print "table.proc caption {color: white; background: DarkSlateBlue; text-align: center}"
print "table.mem {color: DarkGreen; border-color: DarkGreen}"
print "table.mem caption {color: white; background: DarkGreen; text-align: center}"
print "</style>"
print "</head>"
print "<body>"
print "<table><tr>"
}
FILENAME ~ /cpuinfo$/ { print "<td valign=\"top\"><table class=\"proc\">"}
FILENAME ~ /meminfo$/ { print "<td valign=\"top\"><table class=\"mem\">"}
{
for(i=1; i<=NF; i++){
split($i, cpu, ":")
if(i==1) print "<caption>", cpu[1], cpu[2], "</caption>"
else print "<tr><td>", cpu[1], "</td><td>", cpu[2], "</td></tr>"
}
print "</table></td>"
}
END{
# Fin de page HTML
print "</tr></table>"
print "</body>"
print "</html>"
}
A exécuter via la commande suivante :
awk -f infoproc.awk /proc/cpuinfo /proc/meminfo > infoproc.html
Cet exemple regroupe les boucles for, les conditions, l'utilisation de print et les variables possibles.
Pour ce dernier exemple, on regroupe toutes les lignes pour les utiliser dans les $i. Puis ou découpe manuellement la vrai ligne en question pour correspondre à ce que l'on attend. Par conséquent, il ne passera qu'une seule fois par fichier dans le corps du awk.
Fonctions utiles :
Sources de l'article :
LauLem.com - Conditions Générales d'Utilisation - Informations Légales - Charte relative aux cookies - Charte sur la protection des données personnelles - A propos