awk pratique : colonnes, agrégats et rapports
À la fin de ce awk tutoriel pratique, vous saurez découper des lignes en champs (
$1…$NF), réglerFS/OFS, utiliserBEGIN/END, filtrer par motifs, produire des agrégats (somme, compte) et formater avecprintf— sur des CSV et logs factices sous/tmp, enchaînés après grep / ripgrep.Niveau : Intermédiaire · Temps estimé : 45–55 min · Versions testées : Ubuntu 22.04 / 24.04, Debian 12 ; notes Rocky/Alma 9 · Dernière vérification : 2026-09-11
Slug proposé :
linux-awk-pratique· Série : Linux Shell & Automation · Remplace / fusionne : N/A — création (chapitre 3)
Prérequis
- Hub Linux Shell & Automation
- grep et ripgrep (filtrer avant d’agréger) ; bash avancé utile pour encapsuler awk dans un script
awk(mawk ou gawk) déjà présent :awk --versionouawk -W version- Lab
/tmp/lab-awk; pas de données personnelles / secrets
Coût : 0 €. gawk offre parfois plus d’extensions ; les bases ici marchent avec mawk/gawk.
Ce que nous allons construire
Jeux CSV + logs (/tmp)
→ Champs $1..$NF · NF · FS/OFS
→ BEGIN / END · patterns
→ Agrégats : compte, somme, moyenne
→ printf · petit rapport
→ Pipeline grep|awk · nettoyage
(Schéma à remplacer par une image locale Excalidraw / draw.io, alt : « awk pratique : champs NF, BEGIN END, agrégats, printf, rapports ».)
Troisième chapitre de la série. grep/rg sélectionnent des lignes ; awk les structure et calcule. Enchaînement ops classique : rg 'ERROR' fichier | awk '…'. Un bon réflexe : d’abord réduire le bruit (motif, fichier), ensuite seulement compter / sommer — sinon votre tableau associatif grossit pour rien.
Étape 1 — Données lab : CSV et logs
mkdir -p /tmp/lab-awk && cd /tmp/lab-awk
cat > sales.csv << 'EOF'
region,service,amount
eu,api,120
eu,web,80
us,api,200
us,web,50
eu,api,40
ap,api,90
us,api,10
EOF
cat > access.log << 'EOF'
203.0.113.10 200 512
203.0.113.50 401 128
203.0.113.50 401 128
192.0.2.10 200 2
203.0.113.50 500 256
192.0.2.10 200 2
EOF
cat > app.log << 'EOF'
2026-09-11T10:00:01Z INFO boot
2026-09-11T10:00:02Z ERROR db timeout
2026-09-11T10:00:03Z WARN retry
2026-09-11T10:00:04Z ERROR auth failed
2026-09-11T10:00:05Z INFO ok
EOF
wc -l sales.csv access.log app.log
Étape 2 — Champs, NF, FS et OFS
Par défaut, awk découpe sur les espaces / tabulations. $1 = premier champ, $NF = dernier, NF = nombre de champs, $0 = ligne entière.
cd /tmp/lab-awk
# Logs espace-séparés : IP, status, bytes
awk '{print $1, $2}' access.log | head
awk '{print "ip="$1, "bytes="$NF, "nf=" NF}' access.log | head -n 3
# CSV : changer FS
awk -F',' 'NR>1 {print $1, $3}' sales.csv
# OFS : séparateur de sortie
awk -F',' -v OFS=';' 'NR>1 {print $1, $2, $3}' sales.csv | head
| Variable / option | Rôle |
|---|---|
$1 … $n |
Champ n |
$NF |
Dernier champ |
NF |
Nombre de champs de la ligne |
NR |
Numéro de ligne lu (global) |
FS / -F |
Séparateur d’entrée |
OFS |
Séparateur de sortie |
$0 |
Ligne complète |
Ligne d’en-tête CSV :
NR>1pour la sauter, ouNR==1 {next}. Si le séparateur est;(CSV EU), utilisez-F';'— le même principe que pour la virgule.
Étape 3 — BEGIN, END et motifs (patterns)
cd /tmp/lab-awk
# BEGIN : avant la 1re ligne ; END : après la dernière
awk 'BEGIN {print "--- start ---"} {print NR, $0} END {print "--- lines=" NR " ---"}' app.log
# Pattern : seulement les ERROR
awk '/ERROR/ {print $1, $3, $4}' app.log
# Combiner condition et champs (access 4xx/5xx)
awk '$2 >= 400 {print $1, $2}' access.log
# Plusieurs actions
awk '/ERROR/ {err++} /WARN/ {warn++} END {print "err=" err+0, "warn=" warn+0}' app.log
| Bloc | Quand |
|---|---|
BEGIN {…} |
Une fois au démarrage (init, en-têtes) |
pattern {…} |
Pour chaque ligne qui matche |
{…} |
Pour chaque ligne |
END {…} |
Une fois à la fin (totaux, rapports) |
Les variables awk sont initialisées à 0 / "" selon le contexte ; err+0 force l’affichage numérique si aucun match. Les motifs peuvent être des regex (/ERROR|WARN/) ou des expressions ($2>=400) — mélangez-les librement avec && / ||.
Étape 4 — Agrégats : compte, somme, moyenne
cd /tmp/lab-awk
# Bytes totaux + moyenne sur access.log
awk '{sum+=$3; n++} END {print "n=" n, "sum=" sum, "avg=" (n?sum/n:0)}' access.log
# Compteur par IP
awk '{c[$1]++} END {for (ip in c) print c[ip], ip}' access.log | sort -nr
# Somme des amount par région (CSV)
awk -F',' 'NR>1 {sum[$1]+=$3; n[$1]++}
END {
for (r in sum)
printf "%stsum=%dtcount=%dtavg=%.1fn", r, sum[r], n[r], sum[r]/n[r]
}' sales.csv | sort
| Technique | Exemple |
|---|---|
| Accumulateur | sum+=$3 |
| Tableau associatif | c[$1]++ ou sum[$1]+=$3 |
| Moyenne | sum/n dans END (garder n) |
| Tri externe | awk … | sort -nr |
C’est le cœur ops d’awk : un passage, peu de mémoire, rapport immédiat — idéal après un grep/rg qui a réduit le bruit. Pour un top-N, gardez le sort -nr après awk plutôt que de réimplémenter un tri complexe dans le programme.
Étape 5 — printf et petit rapport lisible
Un print concatène avec OFS ; printf contrôle largeur et décimales — indispensable pour coller un rapport dans un ticket ou un mail d’astreinte.
cd /tmp/lab-awk
awk -F',' 'BEGIN {
printf "%-6s %8s %6s %8sn", "region", "sum", "count", "avg"
printf "%-6s %8s %6s %8sn", "------", "---", "-----", "---"
}
NR>1 {sum[$1]+=$3; n[$1]++}
END {
for (r in sum)
printf "%-6s %8d %6d %8.1fn", r, sum[r], n[r], sum[r]/n[r]
}' sales.csv
| Format | Sens |
|---|---|
%s |
Chaîne |
%d |
Entier |
%f / %.1f |
Flottant |
%-6s |
Largeur 6, aligné à gauche |
# Pipeline typique : filtrer puis agréger
grep ERROR app.log | awk '{print $1}'
rg -N ' 401 | 500 ' access.log 2>/dev/null | awk '{c[$1]++} END {for (i in c) print c[i], i}' | sort -nr
# Si rg absent :
awk '$2==401 || $2==500 {c[$1]++} END {for (i in c) print c[i], i}' access.log | sort -nr
Étape 6 — Script réutilisable et nettoyage
cd /tmp/lab-awk
cat > report-sales.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
file=${1:-sales.csv}
[[ -f "$file" ]] || { echo "manque $file" >&2; exit 1; }
awk -F',' -v f="$file" '
NR==1 {next}
{sum[$1]+=$3; n[$1]++}
END {
print "file=" f
for (r in sum)
printf "%s sum=%d count=%dn", r, sum[r], n[r]
}
' "$file"
EOF
chmod +x report-sales.sh
./report-sales.sh sales.csv
cd /tmp
rm -rf /tmp/lab-awk
echo "lab awk nettoyé — OK"
Validé si : vous lisez $NF/NF, changez FS sur un CSV, utilisez BEGIN/END, produisez un compteur par clé et un tableau printf, enchaînez grep/rg → awk. Emportez report-sales.sh comme modèle pour vos prochains exports (coûts cloud, codes HTTP, comptes utilisateur).
Erreurs fréquentes
| Symptôme | Cause | Correction |
|---|---|---|
| Une seule colonne bizarre | Mauvais FS (CSV avec -F' ') |
-F',' ou BEGIN{FS=","} |
| En-tête dans les totaux | NR>1 oublié |
Sauter la ligne 1 |
| Division par zéro | n==0 dans END |
(n?sum/n:0) |
| Ordre des clés « aléatoire » | Parcours for (k in a) non trié |
awk … | sort |
| Espaces dans un champ CSV | CSV naïf vs CSV quoté | Outil CSV dédié ou gawk FPAT (hors cœur) |
Confusion avec bash $1 |
awk vs shell | Guillemets simples autour du programme awk |
grep exit 1 casse le pipe sous set -e |
Voir bash avancé | grep … || true puis awk |
Avant le quiz : retenez la triade FS → pattern → END. Presque tous les one-liners utiles du quotidien tiennent dans ces trois idées ; le reste (printf, tableaux) affine la présentation.
Quiz (3 questions)
1. Que représente $NF ?
– A. Le nombre de fichiers
– B. Le dernier champ de la ligne courante
– C. Le numéro de ligne
2. À quoi sert un bloc END ?
– A. À ignorer les erreurs
– B. À exécuter du code après toutes les lignes (totaux, rapports)
– C. À définir FS uniquement
3. Comment sommer la colonne 3 groupée par la colonne 1 ?
– A. sum[$1]+=$3 dans le corps, affichage dans END
– B. Uniquement grep -c
– C. chmod +x
Réponses : 1‑B · 2‑B · 3‑A
FAQ
awk, cut ou Python ?
cut : découpe simple. awk : conditions + agrégats en un passage, parfait en SSH. Python : logique complexe / CSV riches. Pour 80 % des rapports logs → awk suffit. Dès que vous devez joindre deux fichiers ou parser du JSON, passez à jq / Python — hors cœur de ce chapitre.
mawk ou gawk ?
Les deux exécutent ce lab. gawk ajoute des extensions (réseaux, FPAT…). Sur Ubuntu, awk pointe souvent vers mawk ; sudo apt install gawk si besoin.
Comment éviter que le shell interprète $1 ?
Entourez le programme de simples quotes : awk '{print $1}' fichier. Variables shell : awk -v host="$HOSTNAME" '…'. Double quote autour du programme awk = le shell développe $1 avant awk — source classique de bugs « ça marche dans le tutoriel mais pas chez moi ».
Pour aller plus loin
man awk, guide gawk GNU- Suite : systemd timers : OnCalendar pour DevOps
- Hub : Linux Shell & Automation · préc. grep/ripgrep
Maillage série Linux Shell & Automation
| ← Précédent | grep et ripgrep : chercher dans le code et les logs |
| → Suivant | systemd timers : OnCalendar pour DevOps |
| Hub | Linux Shell & Automation |
Meta publication (à remplir dans Rank Math / SEO)
- Title SEO : awk pratique : colonnes, agrégats et rapports (2026)
- Meta description (≤ 155) : Extraire colonnes et agrégats avec awk (BEGIN/END, NF). Guide Shell Automation DevOps 2026.
- Focus keyphrase : awk tutoriel
- KW secondaires : awk NF, BEGIN END, awk pratique, agrégats awk
- Schemas Rank Math : Article + HowTo (étapes lab) + FAQ (3 questions ci-dessus)
- Image mise en avant :
assets/web/devopelastichayway/cover-linux-awk-pratique-1200x630.webp(Visuels Linux — WebP 1200×630) - Catégorie : Linux · Niveau : Intermédiaire
- Slug :
linux-awk-pratique - Statut : HOLD — draft only (ne pas publier)
← Retour parcours Linux — Basics, Admin, Réseau & Sécurité, Shell & Automation.