Skip to content

awk : Le Couteau Suisse Du Parsing

🎯 Objectifs de ce cours

À la fin, tu seras capable de :

Extraire des colonnes : Beaucoup plus puissant que cut
Filtrer des données : Afficher uniquement ce qui t'intéresse
Faire des calculs : Sommes, moyennes, comptages
Analyser des logs : Compter les 404, les erreurs, les IPs
Parser des formats : CSV, JSON-like, espaces irréguliers
Créer des rapports : Transformer des données brutes en info utile


❌ Le Problème : Analyser 10 000 Lignes De Logs

Imagine ça :

⚠️ Production Error : Beaucoup de 404 sur l'API
   → 10 000 lignes de logs
   → Quelles URLs cassent ?
   → Combien de requêtes par endpoint ?
   → Quel est le taux d'erreur réel ?

Avec grep + cut ?

grep "404" access.log | cut -d' ' -f7 | sort | uniq -c
# Ça marche, mais c'est limité
# Et si tu veux faire des calculs ? Des conditions ?

Avec awk ?

awk '$9 == 404 {print $7}' access.log | sort | uniq -c | sort -rn
# Plus lisible, plus contrôle, plus flexible
❌ cut (limité) ✅ awk (puissant)
Juste extraire une colonne Extraire, filtrer, calculer, tout à la fois
Pas de calculs Sommes, moyennes, comptages en une ligne
Pas de conditions Filtrer les lignes selon n'importe quel critère
Les délimiteurs multiples cassent Gère les espaces irréguliers sans problème

awk c'est ton arme secrète pour les données.


🧱 Comment awk Pense (C'est Un Langage !)

awk fonctionne comme ça :

  1. Lis la ligne du fichier
  2. Coupe la ligne en colonnes (séparées par espace par défaut)
  3. Exécute l'action pour cette ligne
  4. Répète pour toutes les lignes
Fichier
  ↓
[Ligne 1] → {action} → Résultat 1
[Ligne 2] → {action} → Résultat 2
[Ligne 3] → {action} → Résultat 3
  ↓
Sortie

C'est ça, awk. Un petit langage qui traite le fichier ligne par ligne.


📝 La Syntaxe : Simple Mais Puissante

Format de base :

awk 'pattern {action}' fichier.txt

Ou plus court (action par défaut = print) :

awk '{print $1, $3}' fichier.txt

Décomposé :

awk  '{print $1, $3}' access.log
 │    │   │  │ │ │    │
 │    │   │  │ │ │    └─ Fichier à traiter
 │    │   │  │ │ └─ 3ème colonne
 │    │   │  │ └─ Séparateur (virgule)
 │    │   │  └─ 1ère colonne
 │    │   └─ Commande : print (afficher)
 │    └─ L'action (dans les accolades)
 └─ L'outil awk

Important :
- $1 = 1ère colonne
- $2 = 2ème colonne
- $0 = la ligne complète
- Les colonnes sont séparées par espace par défaut


🔍 Les Bases : Colonnes Et Impression

Afficher Une Colonne

awk '{print $1}' access.log

Affiche uniquement la 1ère colonne (généralement l'IP).

Afficher Plusieurs Colonnes

awk '{print $1, $7, $9}' access.log
# IP, URL, Code HTTP

Afficher Avec Mise En Forme

awk '{print "IP: " $1 " | Code: " $9}' access.log

Résultat :

IP: 192.168.1.1 | Code: 200
IP: 192.168.1.2 | Code: 404

Changer Le Séparateur (-F)

Par défaut, awk sépare par un espace. Pour du CSV :

awk -F, '{print $1, $3}' data.csv

Le -F, dit "utilise la virgule comme séparateur".

Autres séparateurs :

awk -F: '{print $1}' /etc/passwd          # /etc/passwd utilise :
awk -F'|' '{print $2}' data.txt           # Utilise |
awk -F'\t' '{print $1}' data.txt          # Utilise une tabulation

🔧 Filtrer Les Données (Patterns)

Afficher Seulement Certaines Lignes

awk '$9 == 404' access.log
# Montre uniquement les lignes où la colonne 9 (code HTTP) = 404

Comparaisons disponibles :

awk '$9 == 404' access.log              # Égal
awk '$9 != 200' access.log              # Pas égal
awk '$9 > 400' access.log               # Supérieur
awk '$9 < 300' access.log               # Inférieur
awk '$1 ~ /192.168/' access.log         # Contient (regex)
awk '$1 !~ /127.0.0.1/' access.log      # Ne contient pas

Combiner Plusieurs Conditions

# Erreurs 404 OU 500
awk '$9 == 404 || $9 == 500' access.log

# Code 200 ET l'URL est /api
awk '$9 == 200 && $7 ~ /\/api/' access.log

# Les requêtes LENTES (> 1000ms)
awk '$10 > 1000' access.log

Exemples DevOps réels :

# Toutes les erreurs
awk '$9 >= 400' /var/log/nginx/access.log

# Requêtes depuis une IP spécifique
awk '$1 == "192.168.1.100"' access.log

# GET requests seulement
awk '$6 ~ /GET/' access.log

🧮 Calculer : Sommes, Moyennes, Comptages

Compter Les Lignes

awk '{n++} END {print "Total: " n}' access.log

Additionner Une Colonne

# Total des bytes transférés
awk '{somme += $10} END {print "Total bytes: " somme}' access.log

# Moyenne du temps de réponse
awk '{total += $10; n++} END {print "Moyenne: " total/n}' access.log

Comment ca marche :
- {total += $10} : Pour CHAQUE ligne, ajoute le contenu de la colonne 10
- END {print total} : APRÈS avoir lu tout le fichier, affiche le total
- n++ : Compteur pour la moyenne

Trouver Min/Max

# Temps de réponse maximum
awk '{if ($10 > max) max = $10} END {print "Max: " max}' access.log

# Temps minimum
awk '{if ($10 < min || min == "") min = $10} END {print "Min: " min}' access.log

📊 Compter Les Occurrences (Tableaux)

C'est là que awk devient vraiment puissant.

Compter Les Requêtes Par URL

awk '{urls[$7]++} END {for (url in urls) print url, urls[$7]}' access.log

Comment ca marche :
- urls[$7]++ : Pour chaque ligne, incrémente le compteur de cette URL
- END {for (url in urls) ...} : Après avoir tout lu, affiche chaque URL + son compteur

Résultat :

/api/users 1250
/api/products 890
/index.html 450
/static/logo.png 200

Compter Les Codes HTTP

awk '{codes[$9]++} END {for (code in codes) print code, codes[$9]}' access.log

Résultat :

200 5000
404 342
500 45

Compter Par IP

awk '{ips[$1]++} END {for (ip in ips) print ip, ips[$1] " requests"}' access.log

🎯 Cas D'Usage DevOps Réels

1️⃣ Analyser Les Erreurs Nginx

# Top 10 des URLs avec 404
awk '$9 == 404 {urls[$7]++} END {for (url in urls) print url, urls[$7]}' \
  /var/log/nginx/access.log | sort -k2 -rn | head -10

2️⃣ Compter Les Erreurs Par Heure

# Log format: [date heure] ...
# Compter les erreurs par heure
awk '$9 >= 500 {hour=$4; gsub(/.*:/, "", hour); hours[hour]++}
     END {for (h in hours) print h, hours[h]}' access.log

3️⃣ Extraire Une IP D'Une Interface

ip addr show eth0 | grep 'inet ' | awk '{print $2}'
# Résultat : 192.168.1.100/24

4️⃣ Parser Un CSV Complexe

# data.csv : name,email,age
awk -F, '{if ($3 > 30) print $1 " (" $2 ")"}' data.csv

5️⃣ Générer Un Rapport De Performance

awk '
  {
    total_requests++
    total_bytes += $10
    response_times[$9]++
  }
  END {
    print "=== Rapport Trafic ==="
    print "Total requêtes: " total_requests
    print "Total bytes: " total_bytes / 1024 / 1024 " MB"
    print "Taux 2xx: " response_times[2] / total_requests * 100 "%"
  }
' access.log

🧬 Combiner awk Avec D'autres Outils

La Chaîne Complète

cat /var/log/nginx/access.log \
  | grep "GET" \
  | awk '$9 >= 400 {print $1, $7, $9}' \
  | sort | uniq -c | sort -rn | head -20

Étape par étape :
1. Lire le log
2. Filtrer les GET uniquement
3. awk extrait IP, URL, Code des erreurs
4. sort + uniq + sort : top 20 des erreurs

Avec sed

# Nettoyer + analyser
sed 's/\[.*\]//' access.log \
  | awk '{print $1, $NF}' \
  | grep -v "404" \
  | awk '{ips[$1]++} END {for (ip in ips) print ip, ips[$1]}'

⚠️ Les Pièges Courants

❌ Erreur ✅ Solution
awk '{print 1}' au lieu de $1 awk '{print $1}' (le $ est important !)
Oublier les accolades awk '{action}' file.txt (accolades obligatoires)
Ne pas mettre -F, pour CSV awk -F, '{print $1}' file.csv (précise le séparateur)
$10 quand il n'y a que 9 colonnes Vérifier ton format : awk 'NF {print NF}' file
Accumulateur non initialisé {n++} crée auto la variable, mais {print n-1} peut être 0

🧠 Variables Utiles À Connaître

# NF = Nombre de colonnes de la ligne courante
awk '{print "Cette ligne a " NF " colonnes"}' fichier.txt

# NR = Numéro de la ligne courante
awk '{if (NR > 5) print}' fichier.txt      # Affiche à partir de la ligne 6

# FILENAME = Nom du fichier courant
awk '{print FILENAME, $1}' fichier.txt

# FS = Field Separator (séparateur)
awk 'BEGIN {FS=":"} {print $1}' /etc/passwd

# OFS = Output Field Separator (séparateur en sortie)
awk '{print $1, $2, $3}' access.log        # Affiche avec espaces
awk 'BEGIN {OFS="|"} {print $1, $2, $3}' access.log  # Affiche avec |

📘 Blocs Spéciaux

BEGIN : Avant De Lire

awk 'BEGIN {print "=== Rapport ==="} {n++} END {print "Total: " n}' access.log

Affiche un header avant de traiter les lignes.

END : Après Avoir Tout Lu

awk '{somme += $1} END {print "Total: " somme}' fichier.txt

Affiche le résultat final après avoir traité tout le fichier.

Pattern : Lignes Qui Correspondent

awk '/error/ {count++} END {print "Erreurs: " count}' app.log
# Compte les lignes contenant "error"

🧾 Cheat Sheet : Commandes Essentielles

But Commande Exemple
Afficher la 1ère colonne awk '{print $1}' awk '{print $1}' access.log
Afficher 2 colonnes awk '{print $1, $7}' awk '{print $1, $7}' access.log
Filtrer les 404 awk '$9 == 404' awk '$9 == 404' access.log
CSV parser awk -F, awk -F, '{print $2}' data.csv
Compter lignes awk '{n++} END {print n}' awk '{n++} END {print n}' file.txt
Somme colonne awk '{s+=$2} END {print s}' awk '{s+=$2} END {print s}' data.txt
Compter occurrences awk '{a[$1]++} END {for (i in a) print i, a[i]}' Top IPs
Ajouter un header awk 'BEGIN {print "Header"} {print}' Rapport
Combiner conditions awk '$9==404 && $7~/api/' Erreurs API
Nombre de colonnes awk '{print NF}' Diagnostic

🎯 Checklist : Tu Maîtrises awk Quand...

  • ✅ Tu extrais facilement des colonnes ($1, $2, etc.)
  • ✅ Tu filtres des lignes avec des conditions
  • ✅ Tu fais une somme/moyenne en une commande
  • ✅ Tu comptes les occurrences d'une valeur
  • ✅ Tu parses des CSV/données structurées
  • ✅ Tu combines awk avec grep/sort/uniq
  • ✅ Tu debugges en testant d'abord sans -i
  • ✅ Tu sais quand utiliser awk vs sed vs grep

🚀 Tips Pro

1️⃣ Teste sur un petit échantillon

# D'abord, teste sur 10 lignes
head -10 access.log | awk '{print $1, $9}'

# Ça marche ? Alors applique au fichier entier
awk '{print $1, $9}' access.log

2️⃣ Affiche NF pour voir les colonnes

awk '{print NF, $0}' access.log | head -1
# Ça te dit combien de colonnes, et la ligne entière

3️⃣ Utilise BEGIN pour initialiser

awk 'BEGIN {print "Démarrage..."} {process} END {print "Fini"}' file.txt

4️⃣ Mets en forme le résultat

# Tableau joli
awk 'BEGIN {printf "%-20s %10s\n", "URL", "Compte"}
     {urls[$1]++}
     END {for (u in urls) printf "%-20s %10d\n", u, urls[$1]}' file.txt

🚀 Prochaines Étapes

Maintenant que tu maîtrises awk :

  • Apprendre les regex avancées : Pour des patterns complexes
  • Créer des scripts awk complets : Dans des fichiers .awk
  • Combiner awk + bash : Automatiser l'analyse de logs
  • Utiliser awk dans des pipelines CI/CD : Générer des rapports
  • Découvrir gawk : Version GNU avec plus de features

awk + grep + sed = la Trinité du DevOps. Ces trois outils te permettent de manipuler TOUTES les données texte. Ensemble, ils sont invincibles. 🏗️

Maintenant que tu maîtrises le terminal, sed et awk, tu peux :
- Parser n'importe quel format
- Nettoyer n'importe quelle donnée
- Automatiser n'importe quel traitement

Bienvenue dans l'élite du DevOps ! 💪