« 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
cutsortuniqawk06Analyse 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"
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.