Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

📜 AWK – Le Guide Ultime

Deep Dive : pattern { action }, $0/$1, FS, NR/NF, BEGIN/END & Tableaux Associatifs.

1.1 Facile

1. C'est quoi AWK ?

Aho, Weinberger, Kernighan. Un langage de scan et de processing de texte (logs, CSV...).

AWK UNIX
1.2 Facile

2. Philosophie & Syntaxe

Le core : pattern { action }. Boucle implicite (ligne par ligne).

pattern action
1.3 Facile

3. Champs & Séparateurs (FS)

$0 (ligne), $1 (champ 1), $NF (dernier). -F (CLI) vs FS (variable).

$0 $1 -F FS
1.4 Moyen

4. Patterns : BEGIN & END

Actions "Setup" (avant la 1ère ligne) et "Cleanup" (après la dernière).

BEGIN END
1.5 Moyen

5. 🔎 Patterns (Regex & Logique)

/regex/, $3 > 100, $1 == "ERROR", /start/,/end/ (Range).

Regex Range
1.6 Facile

6. Actions (Print & Printf)

{ print }, print $1, $3. printf pour le formatage (%-10s).

print printf
2.1 Avancé

7. Variables (NR, NF, FNR)

Variables magiques : NR (N° Ligne), NF (Nb Champs), FNR, RS, OFS.

NR NF FNR
2.2 Moyen

8. Scripts (-f script.awk)

Passer du "one-liner" à un fichier script .awk. Shebang (#!).

-f Shebang
2.3 Moyen

9. Langage (Flow Control)

AWK est un langage : if/else, for, while, next (continue).

if/else for
3.1 Avancé

10. Tableaux Associatifs

La "killer feature". Le "dict" de Python. count[$1]++. Agréger des données.

Arrays Dict
3.2 Moyen

11. Écosystème & "Addons"

gawk (GNU), nawk. Pipeline UNIX : grep | awk | sort | uniq.

gawk grep sed
3.3 Avancé

12. One-Liners & Liens

Cheat-sheet : Compter, Sommer, !seen[$0]++ (unique), Liens (GNU).

One-liner cheat
1.1 C'est quoi AWK ?

AWK est un langage de programmation "orienté-données" conçu pour le traitement de texte avancé. C'est un outil standard sur tous les systèmes UNIX/Linux.

Son nom vient de ses trois créateurs (aux Laboratoires Bell, en 1977) : Alfred Aho, Weinberger, et Kernighan (oui, le "K" de "K&R C").

AWK est un "filtre". Il lit un fichier (ou stdin) ligne par ligne, effectue des actions sur ces lignes, et imprime le résultat. Il est "Turing-complet" (c'est un vrai langage de programmation).

Cas d'Usage (Le "Pourquoi ?")

AWK est le roi quand les données sont structurées en colonnes (logs, CSV, ls -l, etc.).

  • Extraire des colonnes spécifiques d'un fichier (ex: "le 1er et 3ème mot de chaque ligne").
  • Filtrer des lignes basées sur une condition (ex: "lignes où la colonne 3 est > 100").
  • Calculer des statistiques (ex: "faire la somme de la colonne 4").
  • Agréger des données (ex: "compter le nombre d'erreurs par utilisateur").
  • Formater du texte pour des rapports simples.
1.2 Philosophie & Syntaxe : `pattern { action }`

Toute la philosophie d'AWK tient en une seule ligne :

awk 'pattern { action }' fichier.txt
La Boucle Implicite

Pour chaque ligne du fichier.txt, AWK exécute cette logique :

  1. Lire la ligne.
  2. Le Pattern (motif) est-il VRAI pour cette ligne ?
  3. Si OUI, alors exécuter l'Action (le code dans {...}).
  4. Passer à la ligne suivante.
Variations (Toutes optionnelles)
SyntaxeSignification
awk '{ action }'Pattern manquant. Le pattern est "vrai" pour *chaque* ligne. (Le plus courant).
awk '/regex/'Action manquante. L'action par défaut est { print $0 } (imprimer la ligne entière).
awk '/regex/ { action }'Standard. Exécute l'action *seulement* sur les lignes qui matchent le pattern.
Exemple (Hello World)
# Affiche "Hello" pour chaque ligne du fichier 'data.txt'
$ awk '{ print "Hello" }' data.txt

# Affiche UNIQUEMENT les lignes contenant "ERROR"
$ awk '/ERROR/' data.txt

# Affiche "Oops:" SUIVI de la ligne, SI elle contient "ERROR"
$ awk '/ERROR/ { print "Oops:", $0 }' data.txt
1.3 Champs & Séparateurs (FS, -F)

La "magie" d'AWK est qu'il découpe automatiquement chaque ligne en champs (colonnes). Par défaut, le séparateur est "un ou plusieurs espaces ou tabulations".

Variables de Champ
VariableDescription
$0La ligne entière (non modifiée).
$1Le premier champ.
$2Le deuxième champ.
$NFLe dernier champ (NF est une variable, voir 2.1).
Exemple (ls -l)
# Commande 'ls -l' (sortie)
-rw-r--r-- 1 root root 4096 Nov 2 18:00 fichier.txt

# On veut le nom (champ 9) et la taille (champ 5)
$ ls -l | awk '{ print $9, $5 }'
# Sortie: fichier.txt 4096
Changer le Séparateur (-F ou FS)

Pour lire un CSV (séparateur virgule) ou /etc/passwd (séparateur :), on doit changer le "Field Separator" (FS).

Méthode 1 : Option -F (CLI)

Le plus simple. (Note : -F est avant l'apostrophe).

# Fichier: /etc/passwd
# root:x:0:0:root:/root:/bin/bash

# Imprimer le 1er (user) et le 7e (shell) champ
$ awk -F':' '{ print $1, $7 }' /etc/passwd
# Sortie: root /bin/bash
Méthode 2 : Variable FS (Script)

Plus puissant. On le met dans un bloc BEGIN (voir 1.4).

# Fichier: data.csv
# id,nom,prix
# 1,Pomme,1.5

$ awk 'BEGIN { FS = "," } { print $2 }' data.csv
# Sortie:
# nom
# Pomme
1.4 Patterns : `BEGIN` & `END`

BEGIN et END sont deux patterns spéciaux qui ne s'exécutent pas "par ligne".

PatternQuand ?Usage typique
BEGINAvant que la première ligne ne soit lue.Initialiser des variables (sum=0), définir FS, imprimer un en-tête (Header).
ENDAprès que la dernière ligne ait été lue.Imprimer les totaux, les moyennes, ou le contenu d'un tableau associatif (voir 3.1).
Exemple : Compter les lignes et sommer une colonne (CSV)
# Fichier: ventes.csv
# Produit,Quantite
# Pomme,50
# Poire,30
# Banane,100

$ awk '
    # 1. Avant tout
    BEGIN {
        FS = ","
        total = 0
        print "--- Début du Rapport ---"
    }
    
    # 2. Pattern pour ignorer l'"header"
    #    (NR est le N° de ligne, voir 2.1)
    NR > 1 {
        # Action par ligne (ajoute la 2e colonne au total)
        total = total + $2
    }
    
    # 3. Après la dernière ligne
    END {
        print "--- Fin du Rapport ---"
        print "Total des quantités:", total
    }
' ventes.csv

# Sortie:
# --- Début du Rapport ---
# --- Fin du Rapport ---
# Total des quantités: 180
1.5 🔎 Patterns (Regex, Logique & Ranges)

Le "pattern" est la condition qui décide si l'action {...} doit s'exécuter.

1. Pattern "Regex" (/ ... /)

Le plus courant. Utilise des expressions régulières. L'action s'exécute si la ligne ($0) "matche" la regex.

# Imprime les lignes qui contiennent "ERROR" ou "WARN"
awk '/ERROR|WARN/' journal.log

# Imprime les lignes qui commencent par un "timestamp" (ex: 2025-...)
awk '/^[0-9]{4}-/' journal.log
2. Pattern Relationnel (Logique)

Une expression booléenne. Souvent utilisée pour tester la valeur d'un champ.

# Imprime les lignes où le 3e champ est > 100
awk '$3 > 100' data.txt

# Imprime les lignes où le 1er champ est EXACTEMENT "root"
awk -F':' '$1 == "root"' /etc/passwd

# Imprime les lignes avec plus de 5 champs
# (NF = Nombre de Champs, voir 2.1)
awk 'NF > 5' data.txt
3. Pattern "Range" (/start/, /end/)

Un pattern très puissant et unique à AWK/sed. Il "s'active" quand il voit /start/ et "se désactive" quand il voit /end/. Parfait pour extraire des blocs.

# Fichier:
# ...
# START_BLOCK
# Ligne A
# Ligne B
# END_BLOCK
# ...

# Imprime tout ce qui se trouve ENTRE "START_BLOCK" et "END_BLOCK" (inclus)
$ awk '/START_BLOCK/, /END_BLOCK/' fichier.txt
# Sortie:
# START_BLOCK
# Ligne A
# Ligne B
# END_BLOCK
1.6 Actions (Print & Printf)

L'action est le code ({ ... }) qui s'exécute quand le pattern est "vrai".

print

La commande la plus simple. Elle imprime des strings, suivis d'un "Output Record Separator" (ORS), qui est un "newline" (\n) par défaut.

# 'print' sans argument est un alias pour 'print $0'
awk '{ print }' fichier.txt # (Équivalent de 'cat')

# La virgule (,) insère le "Output Field Separator" (OFS)
# (Par défaut, un espace)
awk -F':' '{ print $1, $7 }' /etc/passwd
# Sortie: root /bin/bash

# Sans virgule, il CONCATÈNE les strings
awk -F':' '{ print $1 " -> " $7 }' /etc/passwd
# Sortie: root -> /bin/bash
printf

Pour un formatage "propre" (style langage C). Ne met PAS de "newline" (\n) automatiquement.

SpécificateurDescription
%sString (Chaîne).
%d (ou %i)Entier (Decimal).
%fFlottant (ex: %.2f = 2 décimales).
%-10sString aligné à gauche (padding de 10).
%10sString aligné à droite (padding de 10).
\n, \tNewline (saut de ligne), Tabulation.
Exemple printf
# Objectif : Formater /etc/passwd en colonnes propres

$ awk -F':' 'BEGIN { printf "%-20s | %-15s\n", "UTILISATEUR", "SHELL" } \
           { printf "%-20s | %-15s\n", $1, $7 }' /etc/passwd

# Sortie:
# UTILISATEUR          | SHELL
# root                 | /bin/bash
# daemon               | /usr/sbin/nologin
# ...
2.1 Variables Magiques (NR, NF, FNR, RS, OFS)

AWK fournit de nombreuses variables "magiques" (built-in) qui sont mises à jour automatiquement. Les maîtriser est la clé.

VariableSignificationDescription
$0, $1, ...Champs$0 = Ligne entière, $1 = 1er champ.
NRNumber of RecordsLe N° de la ligne *actuelle* (compteur global, commence à 1).
NFNumber of FieldsLe nombre de champs *dans la ligne actuelle*. ($NF est donc le dernier champ).
FNRFile Number of RecordsLe N° de la ligne *dans le fichier actuel*.
FSField SeparatorLe séparateur d'entrée (défaut: " "). Modifié par -F ou BEGIN { FS="," }.
OFSOutput Field SeparatorLe séparateur de sortie (défaut: " "). Utilisé par print $1, $2.
RSRecord SeparatorLe séparateur d'entrée de ligne (défaut: \n).
ORSOutput Record SeparatorLe séparateur de sortie de ligne (défaut: \n). (Mis par print).
Le "Trick" NR == FNR (Traitement multi-fichiers)

C'est la technique "pro" pour comparer deux fichiers. NR est le compteur global, FNR est le compteur du fichier actuel.
Quand AWK lit le *premier* fichier, NR et FNR sont égaux.
Quand il commence le *deuxième* fichier, FNR repart à 1, mais NR continue de compter.

Objectif : Trouver les utilisateurs de fichierA.txt qui sont *aussi* dans fichierB.txt.

# 1. Lire Fichier A (quand NR == FNR) et stocker les noms dans un tableau 'vu'
# 2. Lire Fichier B (quand NR != FNR) et imprimer si le nom est dans 'vu'

$ awk '
    NR == FNR {
        vu[$1] = 1 # Stocke le 1er champ dans le tableau 'vu'
        next       # (next = 'continue', passe à la ligne suivante)
    }
    
    $1 in vu {
        print $1, "est dans les deux fichiers"
    }
' fichierA.txt fichierB.txt
2.2 Scripts (-f script.awk)

Quand votre "one-liner" devient trop long (plus de 2-3 actions), il est temps de le mettre dans un fichier .awk.

Méthode 1 : One-Liner
$ awk -F',' 'BEGIN { total=0 } NR > 1 { total += $3 } END { print total }' data.csv
Méthode 2 : Fichier Script (-f)

On utilise -f pour spécifier le fichier script.

$ awk -F',' -f mon_script.awk data.csv
mon_script.awk
#!/usr/bin/awk -f
# (Ceci est le "Shebang", pour le rendre exécutable: chmod +x)

# 1. Bloc BEGIN (initialisation)
BEGIN {
    # FS (Field Separator) est mis par le '-F' de la CLI
    
    # OFS (Output Field Separator)
    OFS = "|" # On veut une sortie en "pipe"
    
    total_ventes = 0
    
    # Header
    print "REGION", "TOTAL_VENTES"
}

# 2. Pattern (action par ligne)
# (Ici, on ne veut que la région "Nord" et si la vente > 50)
$1 == "Nord" && $3 > 50 {
    print $1, $3
    total_ventes += $3
}

# 3. Bloc END (résultats)
END {
    print "---", "---"
    printf "TOTAL NORD: %.2f\n", total_ventes
}
2.3 Langage (if, for, while)

AWK n'est pas juste un "filtre", c'est un langage de programmation complet (style C / Python) à l'intérieur des blocs { ... }.

if / else
# { action }
{
    # Note: pas de 'elif', mais 'else if'
    if ($3 > 100) {
        print "Haut:", $0
    } else if ($3 > 50) {
        print "Moyen:", $0
    } else {
        print "Bas:", $0
    }
}
for (Style C)

La boucle for est parfaite pour itérer sur les *champs* d'une ligne.

# Imprimer tous les champs d'une ligne, un par un
{
    # (NF = Nombre de Champs)
    for (i = 1; i <= NF; i++) {
        print "Champ", i, "est:", $i
    }
}
while & next

next est le "continue" de AWK : il arrête de traiter la ligne actuelle et passe à la suivante.

# Ignorer les commentaires
/^[ \t]*#/ {
    next # (Ne pas exécuter les actions suivantes)
}

# Action "normale"
{
    print "Traitement:", $0
}
3.1 Tableaux Associatifs (La "Killer Feature")

C'est la fonctionnalité la plus puissante d'AWK. Les tableaux (Arrays) en AWK ne sont pas numériques (comme en C). Ce sont des tableaux associatifs (comme les dict Python ou les Map JS).

La "clé" (l'index) peut être n'importe quoi (un string, un nombre). C'est parfait pour l'agrégation.

Exemple 1 : Compter les "hits" par IP (Logs)

Objectif : Compter combien de fois chaque IP (champ 1) apparaît dans un log.

# Fichier: access.log
# 1.2.3.4 GET /
# 5.6.7.8 GET /
# 1.2.3.4 GET /page
# 1.2.3.4 POST /login

# L'incrémentation '++' crée la clé si elle n'existe pas (valeur 0)
$ awk '{ count[$1]++ } END { for (ip in count) print ip, count[ip] }' access.log

# Sortie:
# 1.2.3.4 3
# 5.6.7.8 1
Exemple 2 : Sommer les ventes par région
# Fichier: ventes.csv
# Nord,Pomme,50
# Sud,Poire,30
# Nord,Banane,100

$ awk -F',' '{
    # Utilise le champ 1 (Région) comme clé
    # Ajoute le champ 3 (Quantité)
    ventes[$1] += $3
}
END {
    # Itère sur toutes les clés ('Nord', 'Sud')
    for (region in ventes) {
        printf "%-10s : %.2f\n", region, ventes[region]
    }
}' ventes.csv

# Sortie:
# Sud        : 30.00
# Nord       : 150.00
3.2 Écosystème (gawk) & "Addons" (grep, sed)
gawk vs nawk vs mawk

awk est une spécification (POSIX). Il existe plusieurs implémentations ("addons").

  • awk (ou nawk) : Le "New AWK" (des années 80). C'est la base, présente partout.
  • gawk (GNU Awk) : L'implémentation GNU. C'est le standard de facto sur Linux. Il a le plus de fonctionnalités (ex: printf formaté, match(), strftime(), ...).
  • mawk (Mike's Awk) : Une implémentation ultra-rapide, mais avec moins de features que gawk.
La "Trinité" UNIX (grep, sed, awk)

AWK n'est pas seul. Il fait partie de la "chaîne d'outils" (pipeline) UNIX. La philosophie est : "Chaque outil fait une chose, et la fait bien".

OutilSpécialitéCas d'usage
grepFiltrage de lignes (basé sur Regex)."Trouve-moi toutes les lignes contenant 'ERROR'."
sedÉdition de stream (Rechercher/Remplacer)."Sur ces lignes, remplace 'ERROR' par 'WARN'."
awkTraitement de champs/colonnes."Sur ces lignes, prends la 3e colonne et fais la somme."
Exemple de Pipeline (Le "One-Liner")

Objectif : Trouver les 5 utilisateurs qui se sont le plus connectés (sshd) depuis le log.

# 1. Filtre les lignes "Accepted password"
$ grep "Accepted password" /var/log/auth.log | \
  \
  # 2. Extrait le nom d'utilisateur (champ 9)
  awk '{ print $9 }' | \
  \
  # 3. Trie les noms
  sort | \
  \
  # 4. Compte les occurrences uniques
  uniq -c | \
  \
  # 5. Trie numériquement (inverse) et prend le Top 5
  sort -nr | head -n 5
3.3 One-Liners & Liens Utiles
Cheat-Sheet "One-Liners"
# 1. Imprimer la 1ère et 3ème colonne
awk '{ print $1, $3 }' fichier.txt

# 2. Imprimer les lignes de plus de 80 caractères
awk 'length($0) > 80' fichier.txt

# 3. Sommer la 1ère colonne
awk '{ sum += $1 } END { print sum }' fichier.txt

# 4. Compter les lignes (équivalent 'wc -l')
awk 'END { print NR }' fichier.txt

# 5. Imprimer les lignes uniques (équivalent 'uniq')
# (La 'magie' : 'seen[$0]' vaut 0 (false) la 1ère fois, puis 1 (true))
awk '!seen[$0]++' fichier.txt

# 6. Imprimer la 3ème colonne des lignes contenant "ERROR"
awk '/ERROR/ { print $3 }' fichier.txt

# 7. Remplacer "foo" par "bar" sur la 2e colonne (gawk)
awk '{ $2 = gensub(/foo/, "bar", "g", $2); print }' fichier.txt