tuto awk
  • 11 février 2026
  • ComputaSYS
  • 0


Lire un fichier par ligne, découper chaque ligne en champs et vous permettre d’appliquer différents filtres, c’est la mission de la commande awk disponible sous Linux. Ce guide technique va vous aider à prendre en main cette commande indispensable pour manipuler des fichiers bruts, notamment les fichiers de logs.

La commande awk adopte une syntaxe bien particulière qui fait toute sa richesse, notamment avec son système de scripts internes capables de transformer des données brutes en informations exploitables. Grâce à awk, un utilisateur peut accomplir diverses opérations sur une entrée (un texte, un fichier) :

Extraire des colonnes spécifiques d’un fichier.

Effectuer des calculs arithmétiques sur des données chiffrées.

Formater des sorties complexes.

Filtrer des lignes selon des conditions logiques avancées.

Etc.

Awk, c’est plus qu’une simple commande, c’est un langage de traitement de fichiers plats. Il a été créé en 1977 et son nom fait justement référence à ses trois créateurs : Alfred Aho, Peter Weinberger et Brian Kernighan.

Pour traiter les fichiers texte sous Linux, awk est donc complémentaire à d’autres outils comme grep, sed ou encore sort. D’ailleurs, il n’est pas rare de coupler l’utilisation d’awk avec une autre de ces commandes (pour filtrer avec grep puis extraire avec awk, par exemple).

La syntaxe de la commande awk

La puissance de la commande awk réside dans la souplesse de sa syntaxe où les possibilités sont nombreuses, mais c’est aussi ce qui fait sa complexité. Pour bien appréhender le sujet, prenons le temps d’étudier la syntaxe et le fonctionnement interne d’awk.

La structure fondamentale d’une commande awk repose sur une logique simple : pour chaque ligne en entrée, on vérifie si elle correspond à un critère, et si c’est le cas, on exécute une action.

La commande awk s’écrit de plusieurs façons, selon les fonctionnalités utilisées et la complexité de la requête :

awk [option] ‘programme’
awk [option] ‘programme {action}’

La partie programme sert à déterminer les tests et actions à effectuer, et comme nous le verrons par la suite, cela peut aller loin grâce à la prise en charge d’instructions.

Note : si aucun fichier n’est spécifié, awk lira l’entrée standard (stdin), ce qui permet de l’utiliser facilement à la fin d’un pipe (|). Autrement dit, vous pouvez faire un cat ou un grep qui envoie son résultat à awk pour traitement.

Les options

Lorsque vous appelez la commande awk, il n’est pas nécessaire de spécifier une ou plusieurs options. Cependant, il existe beaucoup d’options différentes, notamment celles-ci, fréquemment utilisées :

OptionDescription-FDéfinit un séparateur de champs personnalisé (par défaut, c’est l’espace). Cela est notamment utile pour les CSV afin de préciser le séparateur, généralement la virgule ou le point-virgule.-fLit le programme (script) awk à partir d’un fichier externe.-vAssigne une valeur à une variable avant l’exécution du programme.

L’occasion de préciser que vous pouvez obtenir de l’aide en exécutant cette commande :

awk –help

Le découpage d’une ligne

Quand un fichier est lu à l’aide de la commande awk, il faut savoir que les lignes sont lues une par une et que chaque ligne est découpée en champs de façon automatique. Par défaut, un enregistrement correspond à une ligne, et un champ correspond à un mot séparé par un espace (vous pouvez ajuster via l’option -F).

Au cours de l’exécution et du traitement, cela va donner lieu à un ensemble de variables alimentées automatiquement par awk :

VariableCorrespondance$0La ligne entière$1Le premier champ de la ligne$1, $2, $3…$nLes champs 1, 2 et 3 de la ligne (tout dépend du nombre de valeurs)$NFLe dernier champ de la ligne

Les instructions de contrôle de flux

La commande awk prend en charge des instructions pour le contrôle de flux, comme un moteur de script interne à cet outil : if-else, while, for, break. Ainsi, lors de l’écriture d’une commande awk, vous pouvez utiliser une ou plusieurs instructions et les regrouper à l’aide d’accolades {}.

Voici un tableau récapitulatif des instructions de contrôle de flux (conditions et boucles) utilisées dans awk. Elles suivent une syntaxe très proche du langage C.

InstructionSyntaxe / ExempleDescriptionif / elseif (x > 10) print “Oui”; else print “Non”Exécute une action si la condition est vraie, sinon exécute l’action alternative.whilewhile (i < 5) { print i; i++ }Répète une action tant que la condition est vraie (vérifiée au début).do…whiledo { print i; i++ } while (i < 5)Similaire à while, mais exécute le bloc au moins une fois avant de vérifier la condition.forfor (i=0; i<10; i++) print iBoucle classique avec initialisation, condition et incrémentation.breakif (x == 5) breakSort immédiatement de la boucle en cours (for ou while).continueif (x == 5) continueIgnore le reste du bloc et passe directement à l’itération suivante de la boucle.

Les opérateurs logiques

Voici le tableau pour les opérateurs logiques dans awk. Ils sont essentiels pour combiner plusieurs critères de recherche sur une même ligne.

OpérateurNomDescription&&ET (AND)La condition globale est vraie seulement si les deux conditions sont vraies.||OU (OR)La condition globale est vraie si l’une ou l’autre des deux conditions est vraie.!N’EST PAS (NOT)Inverse le résultat. Si la condition est vraie, elle devient fausse (et vice-versa).

Les blocs spéciaux

Awk supporte deux blocs spéciaux destinés à s’exécuter avant (BEGIN) et après (END) avoir traité l’ensemble du fichier.

CaractéristiqueBloc BEGIN { … }Bloc END { … }Moment d’exécutionAvant de lire la première ligne du premier fichier.Après avoir lu la dernière ligne du dernier fichier.FréquenceS’exécute une seule foisS’exécute une seule foisUsage principal- Initialiser des variables (comme FS, le séparateur de champs, en tant qu’alternative à -F).
– Afficher des titres des colonnes.- Afficher les résultats finaux (sommes, moyennes, etc.).
– Afficher un message de fin.
– Générer un rapport récapitulatif.Accès aux donnéesAucune donnée de fichier n’est disponible, car awk n’a pas commencé à le lire ($0, $1, NF sont vides).Les variables accumulées sont disponibles. Ainsi, $0 contient la dernière ligne lue.

Prise en main d’awk

Désormais, nous allons apprendre à manipuler awk au travers de différents exemples. L’idée étant de commencer avec des choses basiques, avant d’ajouter des éléments supplémentaires pour exploiter le potentiel d’awk et ainsi mettre en pratique ce qui a été évoqué dans la précédente partie de cet article.

Manipuler un fichier texte avec awk

Prenons un exemple simple avec un fichier texte nommé employes.txt, dont le contenu est le suivant :

Florian Burnel France IT-Connect
Mickaël Dorigny France IT-Connect
Guy Mauve France IT-Connect

Si nous souhaitons afficher uniquement le prénom et le nom de l’organisation, nous devrions cibler en principe les champs numéro 1 et 4. En effet, par défaut, awk sépare les champs par un espace. L’instruction print sera utilisée pour afficher les informations dans la console.

Ce qui donne :

awk ‘{ print $1, $4 }’ employes.txt

# Résultat :
Florian IT-Connect
Mickaël IT-Connect
Guy IT-Connect

Remarque : pour aller plus loin dans le formatage de la sortie, vous devez utiliser printf à la place de print, notamment pour limiter le nombre de caractères ou ajuster l’affichage des nombres. Mais, attention, printf n’ajoute pas automatiquement de retour à la ligne, donc vous devez l’ajouter manuellement quand nécessaire via l’ajout de \n dans votre commande.

Manipuler un fichier CSV avec awk

Maintenant, imaginons que notre fichier précédent soit au format CSV avec un contenu plus structuré. Créons le fichier employes.csv avec ce contenu :

Prenom;Nom;Pays;Organisation
Florian;Burnel;France;IT-Connect
Mickaël;Dorigny;France;IT-Connect
Guy;Mauve;France;IT-Connect

Pour obtenir le même résultat que précédemment, nous devons ajouter l’option -F pour préciser que le séparateur entre les champs est le caractère point-virgule.

awk -F’;’ ‘{ print $1, $4 }’ employes.csv

# Résultat :
Prenom Organisation
Florian IT-Connect
Mickaël IT-Connect
Guy IT-Connect

Le résultat précédent correspond à nos attentes, mais il affiche la première ligne correspondante aux en-têtes du fichier CSV. Si l’on veut éliminer cette première ligne, il est nécessaire d’affiner la commande awk. Plusieurs solutions sont envisageables, en voici une :

awk -F’;’ ‘NR > 1 { print $1, $4 }’ employes.csv

Ici, on dit simplement à awk : “Exécute cette action seulement si le numéro de ligne est supérieur à 1”, en faisant référence à NR qui est une variable dynamique qui contient le numéro de la ligne courante (comme un numéro d’index).

Cette syntaxe fonctionne correctement, mais elle montrerait ses limites si l’on traitait plusieurs fichiers CSV. En effet, awk est capable d’agir sur plusieurs fichiers : il suffit de spécifier les noms de fichiers les uns à la suite des autres, en les séparant par un espace.

Si vous traitez plusieurs fichiers CSV en une seule commande, sachez que NR continue de s’incrémenter (il ne revient pas à 1 au début du deuxième fichier). De ce fait, l’en-tête du second fichier ne sera pas supprimée… Pour ignorer l’en-tête de chaque fichier individuellement, utilisez FNR (File Number of Records) à la place de NR, en respectant la même syntaxe.

Les mathématiques avec awk

Awk est capable d’effectuer des opérations simples, comme une addition ou le calcul d’une moyenne, en se référant aux valeurs d’une colonne. C’est notamment applicable sur un fichier CSV. Ajoutons une colonne salaire au fichier CSV utilisé précédemment :

Prenom;Nom;Pays;Organisation;Salaire
Florian;Burnel;France;IT-Connect;2000
Mickaël;Dorigny;France;IT-Connect;2000
Guy;Mauve;France;IT-Connect;1500

Désormais, nous allons justement tenter de faire la somme des salaires et de calculer le salaire moyen.

Additionner l’ensemble des valeurs d’une colonne :

awk -F’;’ ‘NR > 1 { total += $5 } END { print “Total des salaires : ” total ” €” }’ employes.csv

# Résultat :
Total des salaires : 5500 €

Awk est parvenu à faire la somme des salaires grâce à l’utilisation de la variable total (donnez le nom que vous souhaitez). À chaque fois qu’une ligne est traitée, la valeur de la colonne n°5, soit la colonne Salaire, sera ajoutée. Nous n’avons pas eu besoin de déclarer total = 0 au début, car awk initialise automatiquement les variables vides à 0.

C’est la partie clé de cet exemple. Jusqu’ici, toutes les actions que nous écrivions s’exécutaient pour chaque ligne. Si nous avions mis le print à côté du calcul, nous aurions eu un affichage à chaque ligne (par exemple : “Total temporaire : 2000”, “Total temporaire : 4000”, etc.).

Le bloc END est un bloc spécial qui s’exécute une seule fois, uniquement après que la lecture du fichier soit entièrement terminée (comme son nom l’indique). Ce qui signifie que :

Sans END : awk est une boucle qui traite le fichier ligne par ligne.

Avec END : On dit à awk : “Fais tes calculs en silence sur tout le fichier, et une fois que tu as fini de lire la dernière ligne, exécute ce bloc pour me donner le résultat final.”

C’est l’équivalent d’une caissière qui scanne tous vos articles (le bloc principal) et qui, seulement à la fin, appuie sur le bouton “Total” pour vous donner le prix à payer (le bloc END).

Calculer la moyenne :

awk -F’;’ ‘NR > 1 { total += $5; i++ } END { print “Salaire moyen : ” total/i ” €” }’ employes.csv

# Résultat :
Salaire moyen : 1833.33 €

La commande ci-dessus s’appuie sur une variable intermédiaire, nommée i (par habitude), qui s’incrémente (+1) à chaque fois qu’une nouvelle ligne est traitée. Elle sert à compter le nombre de lignes, pour savoir par combien diviser le total afin d’obtenir la moyenne. Le calcul de la moyenne est effectué directement au niveau du print, avec total/n, où j’ai pris soin d’exclure le calcul des blocs entre guillemets.

Même si cette syntaxe permet d’obtenir le résultat attendu, nous aurions pu faire autrement et peut-être même plus simple. En effet, awk contient une variable déjà conçue pour indiquer le numéro de ligne : NR. Ainsi, quand awk est arrivé à la fin du fichier, la variable NR est égale au nombre de lignes. Cela évite de devoir générer une autre variable (comme n), mais attention, nous devons penser à soustraire 1 (soit NR-1) pour ne pas tenir compte de la ligne des en-têtes.

Ce qui donne :

awk -F’;’ ‘NR > 1 { total += $5 } END { print “Salaire moyen : ” total/(NR-1) ” €” }’ employes.csv

# Résultat :
Salaire moyen : 1833.33 €

Enfin, sachez que vous pouvez aussi filtrer les données avec awk. Voici par exemple comment afficher uniquement le nom des personnes qui ont un salaire supérieur ou égal à 2000 euros :

awk -F’;’ ‘NR > 1 && $5 >= 2000 { print $1, $2 }’ employes.csv

Awk supporte les opérateurs de comparaison classiques : ==, !=, <, >, <=, >=. C’est idéal pour filtrer des données numériques.

L’utilisation de if-else avec awk

Amusons-nous à utiliser une structure conditionnelle if-else pour déterminer s’il s’agit d’un salaire de junior ou de sénior. Positionnons le curseur entre les deux statuts à 2000 : toutes les valeurs inférieures correspondent à un profil junior. L’idée étant de voir l’utilisation de if et de else avec Awk.

Nous travaillons toujours sur le même fichier CSV que précédemment.

awk -F’;’ ‘NR > 1 {if ($5 >= 2000) print $1 ” est Senior”; else print $1 ” est Junior”}’ employes.csv

# Résultat
Florian est Senior
Mickaël est Senior
Guy est Junior

Cette commande examine le salaire de chaque employé (colonne 5) pour effectuer un tri automatique. Le bloc conditionnel if agit comme un premier filtre : si la valeur du salaire est supérieure ou égale à 2000, la commande valide la condition (car elle est vraie) et affiche le nom suivi du statut “Senior”. Dans le cas contraire, l’instruction else (sinon) sert d’alternative systématique : elle capture tous les cas qui ont échoué au test précédent (donc tous les salaires inférieurs à 2000) pour leur attribuer par défaut le statut “Junior”.

Modifier le séparateur de la sortie avec OFS

Ce nouvel exemple va permettre de mettre en pratique OFS, ainsi que FS en tant qu’alternative à -F :

FS (Field Separator) : elle définit le séparateur d’entrée. Elle est définie dans un bloc d’initialisation BEGIN.

OFS (Output Field Separator) : définit le séparateur de sortie. Par défaut, lorsque vous faites print $1, $2, awk insère un espace entre les deux valeurs (vous l’avez peut être remarqué avec les exemples précédents). En modifiant la valeur de OFS, vous pouvez formater la sortie différemment.

La commande ci-dessous affiche la liste de tous les utilisateurs du système Linux et leur Shell par défaut, séparés par une flèche sous la forme ->. Cela implique une lecture du fichier /etc/passwd où les valeurs sont séparées par le caractère :.

Ce qui donne :

awk ‘BEGIN {FS=”:”; OFS=” -> “} {print $1, $7}’ /etc/passwd

La sortie sera sous cette forme :

rtkit -> /usr/sbin/nologin
colord -> /usr/sbin/nologin
Debian-gdm -> /bin/false
flo -> /bin/bash

Analyser les logs de connexion SSH

Sur une machine Linux, cherchons à analyser les journaux de connexion SSH pour identifier les tentatives de connexion en échec (mauvais mot de passe). L’objectif étant de sortir une liste des adresses IP à l’origine des tentatives de connexion, tout en spécifiant le nombre d’échecs pour chaque adresse IP. Pour répondre à ce besoin, il est préférable de ne pas utiliser seulement awk, mais plutôt de le coupler à deux autres commandes sort et uniq.

Ce qui donne :

sudo journalctl -u ssh -n 1000 | awk ‘/Failed password/ { for(i=1;i<=NF;i++) if($i==”from”) print $(i+1) }’ | sort | uniq -c | sort -nr

Pour comprendre cette commande, il faut la lire de gauche à droite. Tout simplement parce que chaque étape transforme la donnée pour l’étape suivante.

1 – Récupérer les informations à analyser

Le point de départ pour récupérer les journaux SSH étant d’exécuter cette commande (on récupère uniquement les 1000 dernières lignes dans cet exemple) :

sudo journalctl -u ssh -n 1000

Ici, c’est sur Debian 13 donc il n’y a pas le fichier /var/log/auth.log en absence de rsyslog. C’est pour cette raison que l’on récupère les logs du service SSH de cette façon. Nous obtenons cette sortie (extrait) :

2026 debian-13 sshd-session[110064]: Failed password for invalid user demo from 192.168.14.133 port 64880 ssh2
2026 debian-13 sshd-session[110064]: Connection reset by invalid user demo 192.168.14.133 port 64880 [preauth]
2026 debian-13 sshd-session[110064]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.14.133
2026 debian-13 sshd-session[109982]: pam_unix(sshd:auth): check pass; user unknown
2026 debian-13 sshd-session[109982]: Failed password for invalid user admin from 192.168.14.201 port 49866 ssh2
2026 debian-13 sshd-session[109982]: Connection reset by invalid user admin 192.168.14.201 port 49866 [preauth]
2026 debian-13 sshd-session[109982]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.14.201

2 – Filtrer et extraire les données intéressantes

Ici, awk ne calcule rien. Son seul rôle est de filtrer et d’extraire. Il cherche les lignes Failed password, trouve le mot from, et nous donne juste l’adresse IP qui suit. Une longue liste d’adresses IP en vrac.

sudo journalctl -u ssh -n 1000 | awk ‘/Failed password/ { for(i=1;i<=NF;i++) if($i==”from”) print $(i+1) }’

Pour récupérer l’adresse IP alors que sa position peut changer selon le type d’erreur, nous ne pouvons pas viser une colonne fixe ; c’est ici que le duo for et if agit comme un scanner intelligent. La boucle for (i=1;i<=NF;i++) parcourt la ligne mot par mot, de la gauche vers la droite, tandis que la condition if ($i==”from”) interroge chaque mot pour savoir s’il correspond à notre point de repère “from”.

Dès que ce mot-clé est identifié, awk déduit logiquement que la cible (l’adresse IP) est le mot situé juste après et l’affiche grâce à print $(i+1), garantissant ainsi une extraction de l’adresse IP peu importe la longueur du message de log.

Désormais, les adresses IP sont isolées, puisque cette commande retourne ceci :

192.168.14.133
192.168.14.133
192.168.14.133
192.168.14.201
192.168.14.201
192.168.14.133
192.168.14.133
192.168.14.133
192.168.14.201

3 – Trier les données

Pour que la commande suivante de notre chaine fonctionne correctement (la commande uniq), les données identiques doivent être adjacentes. Grâce à l’utilisation de sort, nous allons pouvoir regrouper toutes les adresses IP identiques (c’est-à-dire à la suite dans la liste).

sudo journalctl -u ssh -n 1000 | awk ‘/Failed password/ { for(i=1;i<=NF;i++) if($i==”from”) print $(i+1) }’ | sort

Désormais, nous obtenons :

192.168.14.133
192.168.14.133
192.168.14.133
192.168.14.133
192.168.14.133
192.168.14.133
192.168.14.201
192.168.14.201
192.168.14.201

4 – Compter les valeurs

Grâce à la commande uniq, nous allons supprimer les doublons, mais en appelant cette commande avec l’option -c (count), un préfixe indiquant combien de fois chaque ligne apparaît est ajouté.

sudo journalctl -u ssh -n 1000 | awk ‘/Failed password/ { for(i=1;i<=NF;i++) if($i==”from”) print $(i+1) }’ | sort | uniq -c

Nous obtenons ce résultat :

6 192.168.14.133
3 192.168.14.201

5 – Le classement final

La dernière étape consiste à appeler une nouvelle fois la commande sort, mais cette fois-ci simplement pour trier le résultat final. L’idée étant d’appeler sort avec ces deux options :

-n (numeric) : pour trier selon la valeur du nombre (et pas alphabétiquement).

-r (reverse) : pour avoir les plus grosses valeurs (donc les adresses IP à l’origine du plus grand nombre de tentatives infructueuses) en haut de la liste.

Voici la commande complète :

sudo journalctl -u ssh -n 1000 | awk ‘/Failed password/ { for(i=1;i<=NF;i++) if($i==”from”) print $(i+1) }’ | sort | uniq -c | sort -nr

Le résultat final (qui aurait pu être différent vis-à-vis de l’étape 4) :

6 192.168.14.133
3 192.168.14.201

Ainsi, nous savons que l’adresse IP 192.168.14.133 a effectué 6 tentatives de connexion SSH en échec, tandis que l’adresse IP 192.168.14.201 en comptabilise 3.

Analyser les logs avec un script awk

Dans l’exemple précédent, nous avons analysé les journaux SSH en couplant awk à deux autres commandes. Sachez que c’était facultatif : awk peut se débrouiller seul. Néanmoins, la méthode précédente offre l’avantage de tenir sur une seule ligne, là où ce sera plus complexe et différent avec awk seul.

C’est l’occasion d’évoquer l’option -f d’awk, car je vous rappelle qu’elle permet de stocker le programme dans un fichier externe (ainsi la logique de traitement s’y trouvera). Nous n’aurons donc pas besoin de charger le terminal, et cela permet aussi de garder de côté le fichier pour le réutiliser.

Créez le fichier analyse_ssh.awk, puis ajoutez ce contenu :

# Fichier : analyse_ssh.awk
# Usage : awk -f analyse_ssh.awk < fichier >

# 1. Le Filtre : On ne traite que les lignes concernées
/Failed password/ {
# On cherche l’IP dynamiquement
for (i=1; i<=NF; i++) {
if ($i == “from”) {
ip = $(i+1)
compteur[ip]++
next # Optimisation : on passe à la ligne suivante
}
}
}

# 2. Le Rapport : S’exécute à la fin du traitement
END {
printf “%-20s %s\n”, “ADRESSE IP”, “TENTATIVES”
print “———————————–”

for (ip in compteur) {
# On pourrait même ajouter un filtre ici (ex: > 10 tentatives)
printf “%-20s %d\n”, ip, compteur[ip]
}
}

Cet exemple fait usage des tableaux associatifs avec Awk. Ils sont très puissants pour regrouper et compter des éléments afin de faciliter l’analyse de données brutes. Contrairement aux langages classiques où les tableaux sont indexés par des numéros (0, 1, 2…), Awk utilise des tableaux associatifs, ce qui signifie que l’index (la clé) peut être du texte, comme une adresse IP, un nom d’utilisateur ou une URL. Dans cet exemple, la clé est ip, d’où la déclaration du tableau via compteur[ip].

Enregistrez et fermez ce fichier.

Puis, appelez ce fichier avec awk :

sudo journalctl -u ssh | awk -f analyse_ssh.awk

Ainsi, la commande n’est pas lourde à lire, le programme étant externalisé dans un fichier. De plus, grâce à l’utilisation du bloc END, nous avons même le luxe d’ajouter des en-têtes avant de passer au comptage des tentatives par IP.

Voici le résultat obtenu dans le Terminal :

ADRESSE IP TENTATIVES
———————————–
192.168.14.201 3
192.168.14.133 6

Filtrage avec les expressions régulières

Les expressions régulières (Regex) apportent une grande souplesse dans le filtrage, que ce soit avec Awk ou tous les autres outils et langages capables de les interpréter. L’idée étant de rechercher des motifs (patterns) plutôt que des valeurs exactes.

La commande ci-dessous scanne le fichier CSV pour afficher intégralement ($0) toutes les lignes contenant le texte 2000. Elle agit comme un filtre de recherche global, ne retenant et n’affichant que les entrées où cette valeur apparaît, quelle que soit la colonne concernée. Ce qui n’est pas sans rappeler ce que permet de faire grep.

L’expression régulière est inscrite entre deux slash :

awk -F’;’ ‘/2000/ { print $0 }’ employes.csv

Dans Awk, on utilise l’opérateur ~ (tilde) pour appliquer la regex à une colonne et vérifier qu’elle correspond à une règle définie entre slashs. Ici, nous cherchons toutes les lignes où la colonne 1 (prenom) commence par la lettre F. Si c’est le cas, la ligne est affichée entièrement.

awk -F’;’ ‘$1 ~ /^F/ { print $0 }’ employes.csv

Analyser les journaux Apache2 avec Awk

La commande ci-dessous sert à afficher les logs d’Apache2 en temps réel, tout en formatant la sortie de façon à afficher uniquement deux informations : l’adresse IP source et la page de destination. Les requêtes pour charger les ressources (images, CSS, JS) sont également exclues grâce à une expression régulière.

sudo tail -f /var/log/apache2/access.log | awk ‘!/\.(jpg|jpeg|png|css|js)/ { print $1 ” -> ” $7 }’

Cette commande retourne une sortie similaire à celle-ci :

X.X.X.X -> /page1
X.X.X.X -> /page2
Y.Y.Y.Y -> /page10
Z.Z.Z.Z -> /page1

Filtrage de processus par utilisateur

Si vous souhaitez lister les processus lancés par un utilisateur spécifique (disons www-data) mais n’afficher que le PID et la commande, vous pouvez compter sur Awk. L’idée étant de voir que cet outil est utile pour filter et formater la sortie des commandes habituelles.

ps -ef | awk ‘$1 == “www-data” {print “PID:”, $2, “| CMD:”, $8}’

# Résultat
PID: 1405 | CMD: php-fpm:
PID: 1406 | CMD: php-fpm:
PID: 3067 | CMD: nginx:
PID: 37149 | CMD: /usr/sbin/apache2
PID: 37150 | CMD: /usr/sbin/apache2

Afficher la liste des adresses IP avec Awk

La commande ip address sert à afficher la configuration IP d’une machine sous Debian ou Ubuntu. Elle fournit la liste des adresses IP configurées, en plus d’autres informations. Comment utiliser Awk pour épurer la sortie de cette commande pour conserver uniquement les adresses IP ? La réponse ci-dessous.

ip a | awk ‘$1 == “inet” { print $2 }’

# Résultat :
127.0.0.1/8
192.168.14.158/24
172.40.0.1/16
172.19.0.1/16
172.17.0.1/16
172.18.0.1/16

Pour comprendre cette commande, il faut regarder la structure de la sortie de la commande ip address. Ci-dessous, j’ai mis en évidence la ligne qui nous intéresse. Étant donné qu’Awk traite les lignes une par une, elles seront traitées de façon indépendante.

1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever

Nous avons donc le filtre $1 == “inet”. Cette condition permet de sélectionner uniquement les lignes IPv4 et d’ignorer les lignes IPv6 (qui commencent par inet6) ou les autres lignes comme celles pour l’adresse MAC (link/ether).

L’action appliquée est { print $2 }, car une fois la bonne ligne trouvée, on affiche simplement le 2ème champ, qui correspond toujours à l’adresse IP suivie de son masque. Le premier champ étant la valeur inet en elle-même.

Conclusion

La commande awk est un pilier de l’administration système sous Linux. Elle intègre un langage capable de réaliser des actions diverses et variées, que ce soit des opérations arithmétiques, de manipuler des chaînes de caractères ou de filtrer finement des données.

Sa maîtrise permet de gagner en efficacité dans la rédaction de scripts, en particulier pour l’automatisation de tâches. Si vous couplez awk avec d’autres outils comme sed, grep ou sort, vous disposez d’un arsenal puissant pour traiter les données directement dans votre terminal.

FAQ – Awk

Quelle est la différence entre awk et sed ?

La commande sed est principalement utilisée pour la modification de texte (chercher/remplacer) sur des flux, tandis que awk est conçu pour le traitement de données structurées (colonnes).

Avec sed, vous pouvez effectuer une action de type “chercher et remplacer” dans un fichier, alors que ce n’est pas la vocation première d’awk. Malgré tout, awk en est capable via l’utilisation des fonctions sub() pour remplacer la première occurrence et gsub() pour remplacer toutes les occurrences.

Comment utiliser un séparateur différent de l’espace ?

Utilisez l’option -F suivie du caractère. Pour un CSV dont le séparateur est la virgule, utilisez awk -F ‘,’ …. L’alternative consiste à utiliser le bloc spécial BEGIN afin de préciser le séparateur via le paramètre FS.

Comment afficher uniquement la dernière colonne d’un fichier ?

Utilisez la variable $NF car elle est conçue pour afficher le dernier champ (attention au séparateur utilisé) : awk ‘{ print $NF }’ fichier.

Comment passer une variable shell externe à awk ?

Utilisez l’option -v. Par exemple : ps -ef | awk -v maVar=”$USER” ‘$1 == ‘maVar’ {print “PID:”, $2, “| CMD:”, $8}’.

Comment compter le nombre de caractères sur chaque ligne ?

Utilisez la fonction length() intégrée à Awk. Exemple : awk ‘{print length($0)}’ fichier. Cette commande retournera seulement le nombre de caractères pour chaque ligne du fichier analysé.

Peut-on traiter plusieurs fichiers à la fois avec awk ?

Oui, spécifiez simplement les noms des fichiers à traiter à la suite : awk ‘{print $0}’ fichier1 fichier2. Quand la commande sera exécutée, Awk les traitera séquentiellement.

Awk peut-il modifier directement un fichier ?

Oui, c’est tout à fait possible en utilisant sub() ou gsub(), selon si vous souhaitez remplacer la première occurrence uniquement ou toutes les occurrences. Mais, ces fonctions seules ne suffisent pas : awk va ajuster la sortie pour appliquer la fonction, mais cela n’écrira pas dans le fichier cible. Il faut donc ajouter -i inplace en complément. Attention, une mauvaise manipulation peut avoir un effet irréversible sur les données de votre fichier. Voici un exemple pour remplacer toutes les occurrences d’un mot par un autre dans un fichier : awk -i inplace ‘{ gsub(“AncienneValeur”, “NouvelleValeur”); print }’ employes.txt

Ingénieur système et réseau, cofondateur d’IT-Connect et Microsoft MVP “Cloud and Datacenter Management”. Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.



Source link

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *