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 :
- Lis la ligne du fichier
- Coupe la ligne en colonnes (séparées par espace par défaut)
- Exécute l'action pour cette ligne
- 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 ! 💪