Document

SUBSCRIBE TO GET FULL ACCESS TO THE E-BOOKS FOR FREE 🎁SUBSCRIBE NOW

Professional Dropdown with Icon

SUBSCRIBE NOW TO GET FREE ACCESS TO EBOOKS

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égler FS/OFS, utiliser BEGIN/END, filtrer par motifs, produire des agrégats (somme, compte) et formater avec printf — 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 --version ou awk -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>1 pour la sauter, ou NR==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

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.