Quand vous travaillez avec des fichiers de logs, des exports CSV ou des données tabulaires, vous avez souvent besoin d'extraire des colonnes, de filtrer des lignes ou de calculer des statistiques. awk est un mini-langage de traitement de texte qui lit un fichier ligne par ligne, découpe chaque ligne en champs ($1, $2...), et permet d'appliquer des conditions et des actions sur ces champs.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Extraire des colonnes spécifiques d'un fichier
- Filtrer des lignes selon des conditions (valeur, regex)
- Effectuer des calculs (somme, moyenne, comptage)
- Utiliser les blocs BEGIN et END pour structurer vos traitements
- Manipuler des fichiers CSV avec un séparateur personnalisé
La commande awk dans l'écosystème Linux
Section intitulée « La commande awk dans l'écosystème Linux »awk fait partie des commandes de traitement de texte sous Linux. Chaque outil a sa spécialité :
| Commande | Spécialité | Quand l'utiliser |
|---|---|---|
awk | Traiter des données en colonnes | Extraire, filtrer, calculer sur des champs |
sed | Éditer des fichiers en flux | Remplacer du texte, supprimer des lignes |
grep | Rechercher par contenu | Filtrer les lignes qui matchent un motif |
cut | Extraire des colonnes simples | Découpage basique par délimiteur |
sort / uniq | Trier et dédupliquer | Classement, comptage d'occurrences |
xargs | Exécuter en masse | Passer des lignes à une commande |
Combinaisons de commandes fréquentes :
La commande awk est souvent utilisée en combinaison avec d'autres outils pour
des traitements plus complexes :
# awk + sort : trier les résultats d'awkawk -F';' '{ print $2, $3 }' ventes.csv | sort -k2 -n
# grep + awk : filtrer puis extrairegrep "ERROR" app.log | awk '{ print $1, $NF }'
# awk + xargs : traitement en masseawk '/pattern/ { print $1 }' fichier | xargs commandeComprendre la commande awk en 2 min
Section intitulée « Comprendre la commande awk en 2 min »🧠 Modèle mental — Comment fonctionne awk
awk = Pour chaque ligne → Si condition vraie → Exécuter action
Points clés
- awk lit le fichier ligne par ligne automatiquement
- Chaque ligne est découpée en champs : $1, $2, $3... ($0 = ligne entière)
- Par défaut, le séparateur est l'espace ou la tabulation
- Sans condition, l'action s'applique à TOUTES les lignes
- BEGIN s'exécute AVANT de lire le fichier (init)
- END s'exécute APRÈS avoir lu tout le fichier (bilan, totaux)
Règles d'or
Vocabulaire essentiel
- $0
- La ligne entière
- $1, $2, $N
- Champ 1, 2, N de la ligne
- $NF
- Dernier champ de la ligne
- NR
- Numéro de la ligne courante
- NF
- Nombre de champs dans la ligne
- FS
- Field Separator (séparateur de champs)
📚 Pour aller plus loin — 12 options avancées
- OFS
- Output Field Separator (séparateur de sortie)
- RS
- Record Separator (séparateur d'enregistrements)
- ORS
- Output Record Separator
- FILENAME
- Nom du fichier en cours de traitement
- FNR
- Numéro de ligne dans le fichier courant
- gsub()
- Remplacer toutes les occurrences
- sub()
- Remplacer la première occurrence
- split()
- Découper une chaîne en tableau
- length()
- Longueur d'une chaîne
- substr()
- Extraire une sous-chaîne
- printf
- Affichage formaté (comme en C)
- arrays[]
- Tableaux associatifs (clé/valeur)
Contrairement à grep (qui filtre des lignes) ou sed (qui modifie en flux), awk est un vrai langage qui permet de traiter chaque ligne comme un enregistrement avec des champs numérotés.
Syntaxe complète
Section intitulée « Syntaxe complète »Deux formes d'appel coexistent, et le choix se fait sur la longueur du programme. En ligne de commande, tout tient entre guillemets simples, obligatoires pour empêcher le shell de remplacer $1 par un argument positionnel avant qu'awk ne le voie. Au-delà de quelques lignes, passez par un fichier .awk avec l'option -f : vous récupérez l'indentation, les commentaires et la coloration syntaxique de votre éditeur.
awk [options] 'programme' fichier(s) # programme écrit dans la ligne de commande, pour les cas simplesawk [options] -f script.awk fichier(s) # programme awk lu depuis un fichier externeStructure du programme :
awk 'BEGIN { init } condition { action } END { final }' fichierOptions principales :
| Option | Description | Exemple |
|---|---|---|
-F sep | Définit le séparateur de champs | awk -F';' '...' (CSV) |
-v var=val | Définit une variable avant l'exécution | awk -v seuil=100 '$2 > seuil' |
-f script | Lit le programme depuis un fichier | awk -f analyse.awk data.txt |
Formes courantes :
# Forme minimale : action sur toutes les lignesawk '{ print $1 }' fichier
# Avec condition : filtrer les lignesawk '/pattern/ { print }' fichierawk '$3 > 100 { print $1, $3 }' fichier
# Avec blocs BEGIN/END : initialisation et finalisationawk 'BEGIN { FS=";" } { sum += $2 } END { print sum }' fichier
# Depuis un pipecat fichier | awk '{ print $NF }'
# Plusieurs fichiersawk '{ print FILENAME, $0 }' fichier1 fichier2Les 3 parties d'un programme awk
Section intitulée « Les 3 parties d'un programme awk »La commande awk suit toujours la même logique :
| Partie | Question | Exemples | Obligatoire ? |
|---|---|---|---|
| Entrée | Quel fichier ou flux traiter ? | fichier.txt, stdin | Fichier ou pipe |
| Condition (motif) | Quelles lignes traiter ? | /ERROR/, $3 > 100, NR > 1 | Non (par défaut : toutes) |
| Action | Que faire sur ces lignes ? | { print $1 }, { sum += $2 } | Non (par défaut : { print }) |
Entrée, awk lit le fichier ou le flux ligne par ligne. Chaque ligne est automatiquement découpée en champs selon le séparateur (espace par défaut).
Condition (optionnelle), Si vous ne mettez pas de condition, l'action s'applique à toutes les lignes. Sinon, seules les lignes qui matchent sont traitées.
Action (optionnelle), Entre accolades { }. Sans action explicite, awk fait { print } (affiche la ligne).
Les variables intégrées : comprendre le découpage
Section intitulée « Les variables intégrées : comprendre le découpage »awk découpe automatiquement chaque ligne en champs numérotés, sans que vous ayez à écrire la moindre ligne de code pour cela. Deux variables du tableau se distinguent des autres et méritent d'être mémorisées en premier : NF compte les champs de la ligne courante, et $NF désigne donc le dernier champ quel que soit le nombre de colonnes. C'est ce qui permet de traiter des lignes de longueur variable, cas courant dans les journaux système. Ne confondez pas NR (le numéro de ligne) avec NF (le nombre de champs) : l'inversion des deux est l'erreur de frappe la plus fréquente chez les débutants.
| Variable | Signification | Exemple |
|---|---|---|
$0 | La ligne entière | print $0 |
$1, $2, $N | Champ 1, 2, N | print $1, $3 |
$NF | Dernier champ | print $NF |
NR | Numéro de ligne (global) | NR > 1 (sauter en-tête) |
NF | Nombre de champs | NF >= 3 |
FS | Séparateur d'entrée | BEGIN { FS=";" } |
Exemple concret :
# Fichier : "Alice 25 Paris"# $1=Alice, $2=25, $3=Paris, NF=3awk '{ print $1, "a", $2, "ans" }' fichier.txt# Résultat : Alice a 25 ansDéfinir le séparateur de champs
Section intitulée « Définir le séparateur de champs »Par défaut, awk sépare sur les espaces et tabulations. Pour un CSV :
# Fichier CSV avec séparateur ;awk -F';' '{ print $1, $3 }' ventes.csv
# Équivalent avec BEGINawk 'BEGIN { FS=";" } { print $1, $3 }' ventes.csvAttention : Piège courant : si $2 est vide ou incorrect, vérifiez que vous avez bien défini -F !
Les filtres : cibler les lignes à traiter
Section intitulée « Les filtres : cibler les lignes à traiter »Les conditions permettent de sélectionner les lignes sur lesquelles appliquer l'action. Repérez la différence entre les deux dernières familles du tableau : /pattern/ teste la ligne entière, alors que $N ~ /regex/ restreint le test à un champ précis. Cette précision évite les faux positifs, par exemple quand vous cherchez un code d'erreur qui pourrait aussi apparaître dans une URL. La condition NR > 1, elle, ne teste aucun contenu : elle sert uniquement à écarter la ligne d'en-tête d'un fichier CSV, geste à faire systématiquement avant tout calcul.
| Condition | Ce qu'elle teste | Exemple |
|---|---|---|
$N == "val" | Égalité stricte | $1 == "admin" |
$N != "val" | Différent de | $3 != "OK" |
$N > val | Supérieur (numérique) | $2 > 100 |
$N ~ /regex/ | Matche la regex | $1 ~ /^192/ |
$N !~ /regex/ | Ne matche pas | $4 !~ /error/ |
/pattern/ | Pattern sur toute la ligne | /ERROR/ |
NR > 1 | À partir de la ligne 2 | Sauter l'en-tête CSV |
Combiner les conditions, ET (&&) / OU (||) / NON (!) :
# ET : les deux conditions doivent être vraiesawk '$2 > 100 && $3 == "OK" { print }' fichier.txt
# OU : au moins une condition vraieawk '$1 == "admin" || $1 == "root" { print }' fichier.txt
# NON : inverser une conditionawk '!($3 ~ /error/) { print }' fichier.txtLes actions : que faire des lignes sélectionnées ?
Section intitulée « Les actions : que faire des lignes sélectionnées ? »Une fois les lignes filtrées, vous pouvez agir dessus. Les deux premières actions du tableau affichent quelque chose immédiatement, les deux suivantes accumulent en mémoire sans rien produire avant le bloc END. Cette distinction explique un étonnement classique : un programme qui ne contient que { sum += $2 } n'affiche rien du tout, puisque personne ne demande jamais le résultat. Les variables d'awk n'ont d'ailleurs pas besoin d'être déclarées : elles valent 0 ou la chaîne vide à leur première utilisation, ce qui permet d'écrire sum += $2 sans initialisation préalable.
| Action | Ce qu'elle fait | Exemple |
|---|---|---|
{ print } | Affiche la ligne (défaut) | { print } |
{ print $1, $3 } | Affiche certains champs | { print $1, $3 } |
{ sum += $2 } | Accumule dans une variable | Calcul de total |
{ count[$1]++ } | Tableau associatif | Comptage par clé |
{ next } | Passe à la ligne suivante | Ignorer cette ligne |
Les blocs spéciaux : BEGIN et END
Section intitulée « Les blocs spéciaux : BEGIN et END »awk propose deux blocs qui s'exécutent avant et après le traitement du fichier. Ils s'exécutent une seule fois, contrairement au corps du programme qui tourne à chaque ligne. BEGIN sert à préparer le terrain, en général définir FS ou afficher un titre de rapport, et il s'exécute même si le fichier est vide ou absent. END sert à restituer ce qui a été accumulé : c'est là que se rendent les totaux, les moyennes et le parcours des tableaux associatifs.
awk 'BEGIN { actions_init } condition { actions } END { actions_fin }' fichier| Bloc | Quand s'exécute | Cas d'usage |
|---|---|---|
BEGIN { } | Avant de lire le fichier | Définir FS, afficher un titre |
END { } | Après avoir lu tout le fichier | Afficher un total, une moyenne |
Exemple complet, Rapport avec total :
awk -F';' ' BEGIN { print "=== Rapport ===" } NR > 1 { total += $3; print $1, $3 } END { print "Total:", total }' ventes.csvEffectuer des calculs
Section intitulée « Effectuer des calculs »awk excelle pour les statistiques simples sur des fichiers. Les quatre exemples ci-dessous partagent la même structure : accumuler dans le corps, restituer dans END. Deux précautions valent pour tous. Ajoutez NR > 1 dès que le fichier possède un en-tête, sinon une ligne de texte entre dans le calcul avec la valeur 0 et fausse la moyenne. Protégez également la division : si aucune ligne n'est traitée, n vaut 0 et awk s'arrête sur une erreur fatale division by zero attempted.
# Somme d'une colonneawk '{ sum += $2 } END { print "Total:", sum }' fichier.txt
# Moyenneawk '{ sum += $2; n++ } END { print "Moyenne:", sum/n }' fichier.txt
# Min et Maxawk 'NR == 1 || $2 > max { max = $2 } END { print "Max:", max }' fichier.txt
# Comptage de lignes selon une conditionawk '$3 == "OK" { count++ } END { print "OK:", count }' fichier.txtTableaux associatifs : regrouper et compter
Section intitulée « Tableaux associatifs : regrouper et compter »Les tableaux associatifs sont la fonctionnalité la plus puissante de awk pour l'analyse : ils remplacent à eux seuls un sort | uniq -c et gèrent des agrégations que ces outils ne savent pas faire. La syntaxe count[$1]++ crée la clé si elle n'existe pas et incrémente sinon, en une seule expression. Un point de vigilance sur le parcours : for (k in arr) restitue les clés dans un ordre non garanti, qui n'est ni l'ordre d'apparition ni l'ordre alphabétique. Pour un résultat classé, passez la sortie à sort, comme le montre le troisième exemple.
# Compter les occurrences par valeurawk '{ count[$1]++ } END { for (k in count) print k, count[k] }' access.log
# Somme par catégorieawk -F';' '{ ventes[$4] += $2 } END { for (v in ventes) print v, ventes[v] }' data.csv
# Combiner avec un tri externeawk '{ count[$1]++ } END { for (k in count) print k, count[k] }' log | sort -k2 -rnFormater la sortie avec printf
Section intitulée « Formater la sortie avec printf »print ajoute automatiquement des espaces et un retour à la ligne. printf offre un contrôle précis de la largeur des colonnes, ce qui devient indispensable dès qu'on produit un rapport lisible plutôt qu'une simple extraction. Le principe est celui du printf du langage C : une chaîne de format contenant des marqueurs, puis les valeurs dans l'ordre. Retenez que la largeur s'exprime en caractères et que le signe moins aligne à gauche : %-15s réserve quinze positions et complète par des espaces à droite.
# Alignement et formatawk '{ printf "%-15s %8.2f€\n", $1, $2 }' prix.txt
# Tableau formatéawk 'BEGIN { printf "%-10s %s\n", "Nom", "Valeur" } { printf "%-10s %d\n", $1, $2 }' fichier.txt| Format | Signification | Exemple |
|---|---|---|
%s | Chaîne | printf "%s", $1 |
%d | Entier | printf "%5d", $2 (5 caractères) |
%.2f | Décimal 2 chiffres | printf "%.2f", $3 |
%-10s | 10 caractères, aligné gauche | printf "%-10s", $1 |
\n | Retour à la ligne | Obligatoire avec printf ! |
Attention : Piège : printf ne met pas de retour à la ligne automatiquement. Ajoutez \n !
Erreurs typiques (et solutions)
Section intitulée « Erreurs typiques (et solutions) »Ces cinq situations couvrent l'essentiel des programmes awk qui « ne marchent pas ». Aucune ne produit de message d'erreur : la commande s'exécute et rend un résultat faux, ce qui est bien plus coûteux à repérer qu'un plantage. Le réflexe de diagnostic est toujours le même, afficher NF et $0 pour vérifier le découpage réel avant de suspecter la logique du programme.
| Erreur | Cause | Solution |
|---|---|---|
$2 est vide ou incorrect | Mauvais séparateur | Définir -F';' pour CSV |
Le shell interprète $1 | Doubles guillemets | Utiliser des guillemets simples : awk '...' |
| L'en-tête est inclus dans les calculs | Pas de filtre | Ajouter NR > 1 |
printf colle tout sur une ligne | Pas de \n | Ajouter \n à la fin du format |
| Comparaison string au lieu de nombre | "9" > "100" est vrai (string) | Forcer avec ($2 + 0) > 100 |
Les modèles de traitement courants
Section intitulée « Les modèles de traitement courants »Maintenant que vous comprenez awk, voici dix modèles prêts à l'emploi, du plus simple au plus avancé. Chacun donne sa formule générale et un exemple concret.
Extraire une colonne
Section intitulée « Extraire une colonne »Afficher un champ précis de chaque ligne. Un numéro de champ qui n'existe pas ne provoque pas d'erreur : awk renvoie une chaîne vide, ce qui produit des lignes blanches plutôt qu'un message explicite.
awk '{ print $N }' fichier # formuleawk '{ print $2 }' fichier.txt # exemple$N: numéro du champ (1, 2, 3…)$0: la ligne entière$NF: le dernier champ
Traiter un CSV
Section intitulée « Traiter un CSV »Lire un fichier avec un séparateur personnalisé. Cette forme ne gère pas les champs quotés contenant le séparateur ("Dupont, Jean") : pour un CSV complexe, passez par un vrai analyseur plutôt que par awk.
awk -F'<sep>' '{ print $1, $3 }' fichier.csv # formuleawk -F';' '{ print $1, $3 }' ventes.csv # exemple-F: définit le séparateur de champs;: séparateur CSV (ou,, ou\t)
Filtrer par condition
Section intitulée « Filtrer par condition »N'afficher que les lignes qui remplissent une condition. La condition se place avant les accolades ; à l'intérieur, elle deviendrait une simple expression sans effet sur la sélection des lignes.
awk '<condition> { action }' fichier # formuleawk '$3 > 100 { print $1, $3 }' fichier.txt # exemple$N == "val": égalité stricte$N > val: comparaison numérique$N ~ /regex/: correspondance d'une expression régulière
Sauter l'en-tête
Section intitulée « Sauter l'en-tête »Ignorer la première ligne, les en-têtes d'un fichier CSV. Avec plusieurs fichiers en argument, NR continue de compter sans se réinitialiser : utilisez alors FNR > 1, qui repart à zéro à chaque fichier.
awk 'NR > 1 { action }' fichier # formuleawk -F';' 'NR > 1 { print $1 }' data.csv # exempleNR: numéro de ligne courant (1, 2, 3…)NR > 1: à partir de la ligne 2
Additionner une colonne
Section intitulée « Additionner une colonne »Calculer le total d'une colonne numérique. La variable sum n'a pas besoin d'être déclarée : elle vaut 0 à sa première utilisation. Ajoutez NR > 1 si le fichier possède un en-tête.
awk '{ sum += $N } END { print sum }' fichier # formuleawk '{ sum += $2 } END { print sum }' ventes.txt # exemplesum += $N: accumule la valeur dans une variableEND: bloc exécuté après la lecture du fichier
Calculer une moyenne
Section intitulée « Calculer une moyenne »Moyenne d'une colonne. Le compteur n est indispensable, car NR compterait aussi les lignes ignorées par la condition. Protégez la division si le fichier peut être vide.
awk '{ sum += $N; n++ } END { print sum/n }' fichier # formuleawk 'NR > 1 { sum += $3; n++ } END { print sum/n }' data.csv # exemplen++: compte le nombre de lignes traitéessum/n: moyenne = total ÷ nombre
Compter par groupe
Section intitulée « Compter par groupe »Regrouper et compter les occurrences avec un tableau associatif. C'est l'équivalent d'un GROUP BY en une ligne. L'ordre de sortie n'est pas garanti : ajoutez | sort pour un résultat stable.
awk '{ count[$1]++ } END { for (k in count) print k, count[k] }' fichier # formuleawk '{ count[$1]++ } END { for (ip in count) print ip, count[ip] }' access.log # exemplecount[$1]++: tableau associatif indexé par$1for (k in arr): parcourt les clés du tableau
Somme par groupe
Section intitulée « Somme par groupe »Additionner une valeur par catégorie. Le même tableau peut porter plusieurs agrégats en parallèle (un pour la somme, un pour le compte), ce qui permet de calculer une moyenne par groupe dans le bloc END.
awk '{ total[$1] += $2 } END { for (k in total) print k, total[k] }' fichier # formuleawk -F';' '{ vente[$4] += $2 } END { for (v in vente) print v, vente[v] }' data.csv # exempletotal[$1] += $2: accumule la valeur de$2par clé$1
Filtrer par expression régulière
Section intitulée « Filtrer par expression régulière »Sélectionner les lignes qui correspondent à un motif. Le motif s'écrit entre slashes, sans guillemets. Écrire "/ERROR/" transformerait la regex en simple chaîne, toujours vraie, et toutes les lignes ressortiraient.
awk '/<pattern>/ { action }' fichier # formuleawk '/ERROR|WARN/ { print }' app.log # exemple/regex/: motif testé sur la ligne entière$N ~ /regex/: motif testé sur un champ précis!~: l'inverse, ne correspond pas
Formater la sortie
Section intitulée « Formater la sortie »Afficher avec un alignement et un format précis. Le nombre de marqueurs doit correspondre au nombre de valeurs fournies : un marqueur en trop affiche une valeur vide ou un zéro, sans le moindre avertissement.
awk '{ printf "%-10s %5d\n", $1, $2 }' fichier # formuleawk '{ printf "%-15s %8.2f€\n", $1, $2 }' prix.txt # exemple%-10s: chaîne sur 10 caractères, alignée à gauche%5d: entier sur 5 caractères%.2f: décimal avec 2 chiffres après la virgule
Les pièges à éviter
Section intitulée « Les pièges à éviter »Six erreurs reviennent constamment avec awk. Pour chacune : la commande piégée, le symptôme, la cause et la correction.
Mauvais séparateur de champs
Section intitulée « Mauvais séparateur de champs »awk '{ print $2 }' fichier.csv # INCORRECT : affiche la ligne entièreSymptôme : $2 est vide ou ne contient pas ce qu'on attend. Cause : le fichier utilise ; ou ,, mais awk découpe sur les espaces par défaut.
awk -F';' '{ print $2 }' fichier.csv # CORRECT : séparateur expliciteConfusion entre guillemets simples et doubles
Section intitulée « Confusion entre guillemets simples et doubles »awk "{ print $1 }" fichier # INCORRECT : le shell remplace $1 avant awkSymptôme : résultat vide ou inattendu. Cause : les guillemets doubles laissent le shell interpréter les $.
awk '{ print $1 }' fichier # CORRECT : guillemets simples : awk reçoit le programme intactEncadrez toujours le programme awk de guillemets simples.
En-tête inclus dans les calculs
Section intitulée « En-tête inclus dans les calculs »awk -F';' '{ sum += $2 } END { print sum }' data.csv # INCORRECT : résultat fauxSymptôme : le total ou la moyenne est incorrect. Cause : la ligne d'en-tête (du texte) est ajoutée au calcul, où elle vaut 0.
awk -F';' 'NR > 1 { sum += $2 } END { print sum }' data.csv # CORRECT : en-tête ignoréComparaison de chaînes au lieu de nombres
Section intitulée « Comparaison de chaînes au lieu de nombres »awk '$2 > "100"' fichier # INCORRECT : "9" > "100" est vrai en comparaison de chaînesSymptôme : une ligne dont le champ vaut 9 ressort alors que vous cherchiez les valeurs supérieures à 100. Cause : dès qu'un des deux opérandes est une constante entre guillemets, awk bascule en comparaison lexicographique, et "9" passe après "100" dans l'ordre des caractères. Le même piège se déclenche si le champ contient autre chose qu'un nombre, par exemple une unité collée (100Mo) ou un séparateur de milliers.
awk '$2 > 100' fichier # CORRECT : constante numérique, comparaison numériqueawk '($2 + 0) > 100' fichier # CORRECT : le + 0 force le contexte numériqueSans guillemets autour de 100, awk applique ses règles de strnum : un champ qui ressemble à un nombre est traité comme tel, la comparaison est donc bien numérique. Le + 0 reste utile pour les champs douteux, puisqu'il convertit explicitement et rend l'intention visible à la relecture.
Condition sans action explicite
Section intitulée « Condition sans action explicite »awk '$3 > 100' fichier # Attention : fonctionne, mais peu lisibleSymptôme : la commande affiche des lignes sans action visible. Cause : sans { }, awk applique { print } par défaut, un comportement implicite peu clair.
awk '$3 > 100 { print }' fichier # CORRECT : action expliciteprintf sans retour à la ligne
Section intitulée « printf sans retour à la ligne »awk '{ printf "%s %s", $1, $2 }' fichier # INCORRECT : toute la sortie sur une seule ligneSymptôme : la sortie est collée, sans retours à la ligne. Cause : contrairement à print, printf n'ajoute pas de saut de ligne automatiquement.
awk '{ printf "%s %s\n", $1, $2 }' fichier # CORRECT : \n explicite en fin de formatTravaux pratiques
Section intitulée « Travaux pratiques »Rien ne remplace la pratique. Créez l'environnement de test ci-dessous, puis déroulez les huit étapes. À la fin, nettoyez avec rm -rf ~/awk-lab.
Préparer le terrain
Section intitulée « Préparer le terrain »Ce script crée quatre fichiers de test dans ~/awk-lab : un CSV de ventes, un log Apache, un relevé de notes et un fichier d'employés.
# Créer le labmkdir -p ~/awk-labcd ~/awk-lab
# Fichier CSV avec séparateur ;cat > ventes.csv << 'EOF'produit;quantite;prix_unitaire;vendeurlaptop;5;899.99;Alicesouris;50;19.99;Bobclavier;30;49.99;Aliceecran;10;299.99;Charlielaptop;3;899.99;Bobsouris;100;19.99;AliceEOF
# Fichier de logs Apachecat > access.log << 'EOF'192.168.1.10 - - [01/Jan/2024:10:00:00] "GET /index.html HTTP/1.1" 200 1234192.168.1.20 - - [01/Jan/2024:10:01:15] "GET /api/users HTTP/1.1" 200 567192.168.1.10 - - [01/Jan/2024:10:02:30] "POST /api/login HTTP/1.1" 401 89192.168.1.30 - - [01/Jan/2024:10:03:45] "GET /index.html HTTP/1.1" 200 1234192.168.1.20 - - [01/Jan/2024:10:04:00] "GET /api/users HTTP/1.1" 500 45192.168.1.10 - - [01/Jan/2024:10:05:10] "GET /images/logo.png HTTP/1.1" 200 5678EOF
# Fichier de notes d'étudiantscat > notes.txt << 'EOF'Alice 15 18 12Bob 10 14 16Charlie 18 17 19Diana 12 11 13Eve 20 19 18EOF
# Fichier avec espaces (plus complexe)cat > employes.txt << 'EOF'Jean Dupont;Développeur;45000Marie Martin;Chef de projet;55000Pierre Durand;Administrateur;50000Sophie Bernard;Développeur;48000EOF
echo "Lab créé dans ~/awk-lab"ls -la ~/awk-labLes huit étapes
Section intitulée « Les huit étapes »Ces huit commandes ne modifient aucun fichier : elles affichent leur résultat à l'écran, vous pouvez donc les rejouer autant de fois que nécessaire. La progression suit l'ordre dans lequel on construit un traitement réel : d'abord découper correctement, ensuite filtrer, enfin calculer et formater. Comparez systématiquement la sortie obtenue au résultat annoncé ; un écart signale presque toujours un problème de séparateur ou de numéro de champ.
-
Afficher une colonne spécifique. Affiche uniquement la première colonne (produit) du fichier CSV.
Fenêtre de terminal awk -F';' '{ print $1 }' ~/awk-lab/ventes.csvRésultat attendu : la liste des produits (
laptop,souris,clavier,ecran…).-F';'définit le séparateur,$1cible le premier champ. -
Sauter l'en-tête. Affiche les produits sans la ligne d'en-tête.
Fenêtre de terminal awk -F';' 'NR > 1 { print $1 }' ~/awk-lab/ventes.csvNRest le numéro de ligne ;NR > 1saute la première ligne (produit). -
Filtrer par valeur. Affiche uniquement les ventes réalisées par Alice.
Fenêtre de terminal awk -F';' '$4 == "Alice" { print }' ~/awk-lab/ventes.csv$4 == "Alice"teste si le quatrième champ vaut exactementAlice, trois lignes correspondent. -
Calculer un total. Calcule le total des quantités vendues.
Fenêtre de terminal awk -F';' 'NR > 1 { total += $2 } END { print total }' ~/awk-lab/ventes.csvRésultat attendu :
198(5+50+30+10+3+100).total += $2accumule,ENDaffiche après la lecture. -
Calculer une moyenne. Calcule la moyenne des trois notes de chaque étudiant.
Fenêtre de terminal awk '{ moy = ($2 + $3 + $4) / 3; print $1, moy }' ~/awk-lab/notes.txtOn effectue le calcul directement dans
awk. Pas besoin de-Fici : le séparateur par défaut (l'espace) convient. -
Compter par catégorie. Compte le nombre de ventes par vendeur.
Fenêtre de terminal awk -F';' 'NR > 1 { count[$4]++ } END { for (v in count) print v, count[v] }' ~/awk-lab/ventes.csvRésultat attendu :
Alice 3,Bob 2,Charlie 1.count[$4]++utilise un tableau associatif indexé par le vendeur. -
Filtrer avec une expression régulière. Affiche les lignes du log contenant une erreur (code HTTP 4xx ou 5xx).
Fenêtre de terminal awk '$8 ~ /^[45]/ { print }' ~/awk-lab/access.logRésultat attendu : deux lignes, les codes
401et500. Comptez les champs avant d'écrire la commande : sur ce format de log,$8porte le code HTTP et$9la taille de la réponse. Sur un journal Apache complet, l'horodatage contient un fuseau ([01/Jan/2024:10:00:00 +0100]) qui ajoute un champ et décale tout d'un rang. La commandeawk '{ print NF, $0 }'lève le doute en une seconde. -
Formater la sortie. Affiche les employés avec leur salaire suivi du symbole €, en colonnes alignées.
Fenêtre de terminal awk -F';' '{ printf "%-20s %s€\n", $1, $3 }' ~/awk-lab/employes.txtprintfpermet un formatage précis :%-20sréserve 20 caractères alignés à gauche.
Exercices progressifs
Section intitulée « Exercices progressifs »Huit exercices pour valider votre maîtrise, du plus simple au plus complet. Tous se traitent sur les fichiers du lab ~/awk-lab (ou sur /etc/passwd). Cherchez d'abord par vous-même, puis dépliez la solution pour vous corriger.
Niveau fondations
Section intitulée « Niveau fondations »Ces trois exercices portent sur le geste de base : découper et afficher. Deux d'entre eux utilisent /etc/passwd, un fichier présent sur toutes les distributions et séparé par des deux-points, ce qui oblige à penser à l'option -F dès la première commande. Vérifiez votre résultat en le comparant à cut -d: -f7 /etc/passwd : les deux outils doivent produire exactement la même sortie.
Exercice 1, Afficher la dernière colonne. Affichez la dernière colonne de chaque ligne de /etc/passwd. Indice : $NF représente le dernier champ.
Voir la solution
awk -F':' '{ print $NF }' /etc/passwd/etc/passwd utilise : comme séparateur ; $NF cible le dernier champ, le shell de chaque utilisateur.
Exercice 2, Filtrer les utilisateurs avec un shell. Affichez les utilisateurs dont le shell est /bin/bash. Indice : filtrez sur $7.
Voir la solution
awk -F':' '$7 == "/bin/bash" { print $1 }' /etc/passwd$7 est le champ shell dans /etc/passwd ; on teste l'égalité stricte, puis on affiche le nom ($1).
Exercice 3, Numéroter les lignes. Affichez chaque ligne du fichier notes.txt précédée de son numéro. Indice : NR contient le numéro de ligne.
Voir la solution
awk '{ print NR, $0 }' ~/awk-lab/notes.txtNR = numéro de ligne courant, $0 = ligne entière.
Niveau composition
Section intitulée « Niveau composition »On passe ici à l'accumulation : le résultat ne s'affiche plus ligne par ligne mais une seule fois, dans le bloc END. Les deux exercices exigent de sauter l'en-tête ou de maîtriser le formatage. Si votre total paraît trop élevé de quelques unités, l'en-tête a probablement été compté ; s'il est décimal alors que vous attendiez un entier, vérifiez la colonne visée.
Exercice 4, Total d'une colonne CSV. Calculez le total de la colonne prix_unitaire de ventes.csv (séparateur ;). Indice : accumulez avec += et affichez dans END.
Voir la solution
awk -F';' 'NR > 1 { total += $3 } END { print total }' ~/awk-lab/ventes.csvNR > 1 saute l'en-tête ; le bloc END s'exécute après la lecture complète.
Exercice 5, Moyenne avec formatage. Calculez la moyenne de la colonne 2 de notes.txt et affichez-la avec 2 décimales. Indice : printf "%.2f".
Voir la solution
awk '{ sum += $2; n++ } END { printf "Moyenne : %.2f\n", sum/n }' ~/awk-lab/notes.txtprintf formate la sortie ; %.2f impose deux décimales.
Niveau industrialisation
Section intitulée « Niveau industrialisation »Ces deux exercices reproduisent une analyse de journal réelle : agréger par clé et isoler les erreurs. Le premier introduit le tableau associatif, le second demande de repérer le bon champ avant d'écrire la regex. Aucun des deux ne se résout de tête : commencez par afficher les champs numérotés pour situer l'information.
Exercice 6, Compter les requêtes par IP. Comptez combien de requêtes chaque IP a faites dans access.log. Indice : tableau associatif indexé par $1.
Voir la solution
awk '{ count[$1]++ } END { for (ip in count) print ip, count[ip] }' ~/awk-lab/access.logcount[$1]++ crée un compteur par IP ; for (k in arr) parcourt les clés.
Exercice 7, Filtrer les erreurs HTTP. Affichez uniquement les lignes d'access.log dont le code HTTP est une erreur (4xx ou 5xx). Indice : commencez par compter les champs avec awk '{ print NF, $0 }' pour situer le code.
Voir la solution
awk '$8 ~ /^[45][0-9][0-9]$/ { print }' ~/awk-lab/access.log~ teste une expression régulière ; ^[45][0-9][0-9]$ impose exactement trois chiffres commençant par 4 ou 5. Le code se trouve en $8 sur ce fichier : $9 contient la taille de la réponse, et le filtrer donnerait des lignes en 200.
Niveau synthèse
Section intitulée « Niveau synthèse »Le dernier exercice combine tout : BEGIN pour l'en-tête, le corps pour les données et l'accumulation, END pour le total. C'est la structure exacte de n'importe quel rapport produit avec awk, et savoir l'écrire de mémoire constitue un bon critère de maîtrise. Soignez l'alignement : des largeurs identiques entre l'en-tête et les lignes de données font toute la lisibilité.
Exercice 8, Rapport formaté avec totaux. Générez, à partir de ventes.csv, un rapport avec en-tête, données alignées et total final. Indice : BEGIN pour l'en-tête, printf pour l'alignement, END pour le total.
Voir la solution
awk -F';' ' BEGIN { printf "%-15s %10s\n", "Produit", "Prix" } NR > 1 { printf "%-15s %10.2f\n", $1, $3; total += $3 } END { printf "%-15s %10.2f\n", "TOTAL", total }' ~/awk-lab/ventes.csvBEGIN pose les titres, le corps traite chaque ligne, END affiche le bilan, la structure type d'un rapport awk.
Dépannage
Section intitulée « Dépannage »Quand un programme awk ne donne pas le résultat attendu, le problème vient presque toujours du découpage en champs. Voici comment diagnostiquer.
Méthodes de diagnostic
Section intitulée « Méthodes de diagnostic »Ces quatre commandes répondent à une seule question, posée dans l'ordre : qu'est-ce qu'awk voit réellement ? La deuxième est la plus rentable, car un NF inattendu révèle immédiatement un mauvais séparateur ou des lignes irrégulières. La troisième numérote chaque champ et sert quand vous ne savez plus dans quelle colonne se trouve l'information cherchée. La quatrième limite le travail à quelques lignes, réflexe utile sur un journal de plusieurs gigaoctets.
# Voir ce qu'awk reçoit réellement (numéro de ligne + ligne)awk '{ print NR, $0 }' fichier
# Vérifier le nombre de champs détectés sur chaque ligneawk '{ print NF, $0 }' fichier
# Afficher chaque champ séparément, numérotéawk -F';' '{ for (i=1; i<=NF; i++) print i, $i }' fichier
# Tester sur quelques lignes seulement, sans traiter tout le fichierhead -5 fichier | awk '...'Erreurs fréquentes
Section intitulée « Erreurs fréquentes »Contrairement aux erreurs de logique vues plus haut, ces trois cas provoquent un message explicite et un code de retour non nul. awk indique le numéro de ligne du programme fautif, ce qui aide surtout quand le programme est dans un fichier .awk. La division par zéro est particulièrement traître : elle survient dans le bloc END après un traitement apparemment réussi, quand aucune ligne n'a alimenté le compteur.
| Message d'erreur | Cause probable | Solution |
|---|---|---|
awk: syntax error at source line 1 | Guillemets ou accolades { } mal fermés | Vérifier que les guillemets simples encadrent tout le programme et que chaque { a son } |
awk: illegal field $() | Le shell a interprété $1 avant awk | Encadrer le programme de guillemets simples : awk '...', jamais awk "..." |
awk: division by zero | Le diviseur vaut 0 (fichier vide, compteur nul) | Protéger le calcul : END { if (n > 0) print sum/n } |
Aide-mémoire awk
Section intitulée « Aide-mémoire awk »Les cinq tableaux qui suivent rassemblent ce qui sert au quotidien, classé par nature. Ils sont pensés pour la consultation rapide en cours de rédaction d'une commande, pas pour l'apprentissage : si un élément vous surprend, revenez à la section correspondante plus haut.
Syntaxe générale
Section intitulée « Syntaxe générale »Les trois formes ci-dessous couvrent tous les usages. La troisième est la structure complète, celle vers laquelle tend n'importe quel traitement un peu ambitieux : initialiser, traiter chaque ligne, conclure. Notez que les blocs sont tous facultatifs et peuvent apparaître dans n'importe quel ordre, même si l'ordre naturel reste le plus lisible.
| Élément | Rôle | Exemple |
|---|---|---|
awk [options] '{ programme }' fichier(s) | Format général de la commande | awk '{ print $1 }' data.txt |
awk [options] -f script.awk fichier(s) | Programme lu depuis un fichier externe | awk -f analyse.awk data.csv |
awk 'BEGIN {…} condition {…} END {…}' fichier | Structure complète avec blocs spéciaux | awk 'BEGIN{s=0} {s+=$1} END{print s}' |
Trois options suffisent en pratique. -F définit le séparateur d'entrée et remplace un BEGIN { FS=";" } plus verbeux. L'option -v est la seule façon propre de faire entrer une valeur du shell dans le programme : elle évite d'ouvrir des guillemets doubles, donc de laisser le shell interpréter les $. Elle s'utilise aussi pour redéfinir une variable interne, par exemple -v OFS=",".
| Option | Rôle | Exemple |
|---|---|---|
-F sep | Définit le séparateur de champs | awk -F';' '...' data.csv |
-v var=val | Définit une variable avant l'exécution | awk -v seuil=100 '$2 > seuil' |
-f script.awk | Lit le programme depuis un fichier | awk -f analyse.awk data.txt |
Variables intégrées
Section intitulée « Variables intégrées »Ces variables sont mises à jour automatiquement à chaque ligne lue, vous n'avez jamais à les alimenter. La distinction à retenir oppose FS, le séparateur en entrée, à OFS, le séparateur en sortie. Redéfinir OFS n'a d'effet que si vous utilisez la virgule dans un print : print $1, $2 respecte OFS, alors que print $1 $2 colle les deux champs sans rien insérer.
| Variable | Rôle | Exemple |
|---|---|---|
$0 | La ligne entière | print $0 |
$1, $2, $N | Champ 1, 2, N | print $1, $3 |
$NF | Le dernier champ | print $NF |
NR | Numéro de ligne (global) | NR > 1 |
NF | Nombre de champs de la ligne | NF >= 3 |
FS | Séparateur d'entrée | BEGIN { FS=";" } |
OFS | Séparateur de sortie | BEGIN { OFS="," } |
Conditions
Section intitulée « Conditions »Toute condition d'awk se ramène à une expression qui vaut vrai ou faux, ce qui autorise à les combiner librement avec &&, || et la négation !. Attention à la comparaison d'égalité : == compare, = affecte. Écrire $1 = "admin" remplace le premier champ au lieu de le tester, et le programme s'exécute sans la moindre erreur en réécrivant vos données.
| Condition | Rôle | Exemple |
|---|---|---|
$N == "val" | Égalité stricte | $1 == "admin" |
$N ~ /regex/ | Correspond à une regex | $1 ~ /^[A-Z]/ |
$N !~ /regex/ | Ne correspond pas | $2 !~ /error/ |
/pattern/ | Correspond sur la ligne entière | /ERROR/ |
&& || | ET / OU logiques | $2 > 0 && $3 < 100 |
Blocs, fonctions et affichage
Section intitulée « Blocs, fonctions et affichage »Ce dernier tableau regroupe les fonctions intégrées les plus utiles. Trois d'entre elles rendent awk autonome sur des traitements qu'on confie souvent à sed : gsub() remplace toutes les occurrences directement dans un champ, substr() extrait une portion de chaîne, et split() découpe une valeur en tableau, ce qui permet un second niveau de découpage à l'intérieur d'un champ déjà séparé.
| Élément | Rôle | Exemple |
|---|---|---|
BEGIN { } | Bloc exécuté avant la lecture | BEGIN { print "Titre" } |
END { } | Bloc exécuté après la lecture | END { print total } |
length() | Longueur d'une chaîne | length($1) |
substr(s,i,n) | Extrait une sous-chaîne | substr($1,1,3) |
gsub(r,s) | Remplace toutes les occurrences | gsub(/old/,"new") |
split(s,a,fs) | Découpe une chaîne en tableau | split($1,parts,"-") |
tolower() / toupper() | Change la casse | tolower($1) |
print | Affiche (avec saut de ligne) | print $1, $2 |
printf | Affichage formaté, sans saut auto | printf "%-10s", $1 |
%s / %d / %.2f | Chaîne / entier / décimal | printf "%.2f", $3 |
arr[$1]++ | Compteur par clé | count[$1]++ |
for (k in arr) | Parcourt les clés d'un tableau | for (ip in count) |
delete arr[k] | Supprime une clé | delete data["tmp"] |
Checklist de maîtrise
Section intitulée « Checklist de maîtrise »Vous maîtrisez awk lorsque vous pouvez cocher chacun de ces points :
- Je sais extraire une colonne avec
$N - Je sais définir un séparateur avec
-F - Je sais filtrer les lignes avec une condition
- Je sais utiliser
NR,NFet$0 - Je sais calculer une somme avec le bloc
END - Je sais formater une sortie avec
printf - Je sais utiliser les tableaux associatifs
- Je sais filtrer avec une expression régulière (
~) - Je sais structurer un traitement avec
BEGINetEND - Je sais générer un rapport complet avec en-tête et total
Conclusion
Section intitulée « Conclusion »La commande awk est un outil fondamental pour quiconque travaille avec des données textuelles. Grâce à son découpage automatique en champs, ses conditions flexibles et ses capacités de calcul, elle permet de traiter, analyser et transformer des fichiers structurés en quelques lignes. Que ce soit pour parser des logs, traiter des CSV ou générer des rapports, la maîtrise de awk vous fera gagner un temps considérable.
FAQ - Questions Fréquemment Posées
Section intitulée « FAQ - Questions Fréquemment Posées »Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications