Linux — utilisation avancée et administration · Étape 23

Structure et agrège avec cut, sort, uniq et awk

Découpe des champs, trie avec une locale contrôlée, compte correctement et produit des indicateurs à partir de CSV et logs.

Durée indicative · ~1 h 40Niveau intermédiairePrérequis conseillé · Leçon 22 — grep, sed et trPratique · TP
L’idée reçue

« uniq compte toutes les valeurs identiques où qu’elles se trouvent. »

uniq compare seulement les lignes adjacentes. Pour compter un ensemble non trié, il faut généralement utiliser sort | uniq -c ou une agrégation awk.

01Découpe un fichier délimité

export LAB="/tmp/soria-linux-text-$USER"
cut -d, -f1,2,4 "$LAB/data/inventory.csv"
cut -d'|' -f1,3,4 "$LAB/data/services.psv"

cut convient lorsque le séparateur est simple et qu’aucun champ ne contient lui-même ce séparateur. Ce n’est pas un parseur CSV complet avec guillemets et virgules échappées.

02Trie avec une intention explicite

LC_ALL=C sort -t, -k4,4 -k1,1 "$LAB/data/inventory.csv"
LC_ALL=C sort -t'|' -k4,4nr "$LAB/data/services.psv"
LC_ALL=C rend l’ordre lexical reproductible. -n demande un tri numérique et -r inverse l’ordre.

03Compte avec sort et uniq

tail -n +2 "$LAB/data/inventory.csv" | cut -d, -f4 | LC_ALL=C sort | uniq -c

grep -Eo 'status=[0-9]{3}' "$LAB/data/access.log" | cut -d= -f2 | LC_ALL=C sort | uniq -c | sort -nr

tail -n +2 retire l’en-tête avant le comptage. Sans cette étape, le nom de colonne devient une valeur de données.

04Filtre et calcule avec awk

awk -F, '
NR == 1 { next }
$4 == "production" { count++; ram += $6 }
END {
print "production_hosts=" count
print "production_ram_mb=" ram
}
' "$LAB/data/inventory.csv"

awk lit une ligne, la découpe selon FS, applique les règles puis exécute la section END après la dernière ligne.

05Utilise un tableau associatif

awk -F, '
NR == 1 { next }
{ hosts[$7]++; ram[$7] += $6 }
END {
for (owner in hosts)
  printf "owner=%s hosts=%d ram_mb=%d
", owner, hosts[owner], ram[owner]
}
' "$LAB/data/inventory.csv" | LC_ALL=C sort
Outil
Bon usage
Limite principale
cut
colonnes simples
pas de logique ni CSV complexe
sort
ordre et préparation de regroupement
locale et type numérique à préciser
uniq
doublons adjacents
nécessite souvent un tri préalable
awk
validation, calcul et agrégation
script à structurer quand il grandit

06Analyse le log HTTP en une passe

awk '
{
status=""; duration=""; client=""
for (i=1; i<=NF; i++) {
  split($i, pair, "=")
  if (pair[1] == "status") status=pair[2]
  if (pair[1] == "duration_ms") duration=pair[2]
  if (pair[1] == "client") client=pair[2]
}
if (status !~ /^[0-9][0-9][0-9]$/) { malformed++; next }
counts[status]++
clients[client]=1
if (duration >= 250) slow++
}
END {
for (status in counts) print status, counts[status]
print "malformed", malformed
print "slow", slow
}
' "$LAB/data/access.log" | LC_ALL=C sort

La ligne malformée est comptée puis ignorée. Un traitement robuste ne suppose pas silencieusement que toutes les entrées sont valides.

07Valide contre une sortie attendue

grep -Eo 'status=[0-9]{3}' "$LAB/data/access.log" | cut -d= -f2 | LC_ALL=C sort | uniq -c | awk '{ print $2, $1 }' > "$LAB/tmp/status-counts.txt"

diff -u "$LAB/expected/status-counts.txt" "$LAB/tmp/status-counts.txt"
Challenge autonome

Construis un tableau d’exploitation

À partir de inventory.csv et services.psv, produis par owner le nombre d’hôtes, la RAM totale, le nombre de services non-ok et la latence maximale. Trie la sortie et documente les hypothèses de format.

Ce que tu retiens

cut découpe, sort ordonne, uniq compte les voisins et awk porte la logique d’agrégation. Un rapport fiable fixe le séparateur, la locale, le type de tri et le comportement face aux lignes malformées.

Ta progression

Chargement de l’état… Se connecter pour synchroniser.