Agrégation avec les tableaux et le regroupement dans awk
Calculez des sommes, des décomptes et des synthèses par groupe à l’aide de tableaux associatifs indexés par les valeurs des champs.
Agrégation avec les tableaux et le regroupement dans awk est une leçon Linux Command Line & Bash Scripting Mastery gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Linux Command Line & Bash Scripting Mastery, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Linux Command Line & Bash Scripting Mastery comprend 4 leçons au total.
Que sont les tableaux associatifs awk ?
Dans awk, un tableau associatif est un magasin clé-valeur dont les clés peuvent être des chaînes ou des nombres. Contrairement aux tableaux indexés de la plupart des langages, les tableaux awk sont en réalité des tables de hachage — parfaites pour regrouper et agréger les données selon les valeurs des champs.
- Déclaration implicite : il suffit d’affecter une valeur à
arr[key] = value - Les clés sont des chaînes par défaut (les nombres sont convertis)
- Aucune limite de taille — awk agrandit le tableau selon les besoins
- Idéal pour calculer des sommes, des comptes et des regroupements en une seule passe
Il n’est pas nécessaire d’initialiser une clé avant de l’incrémenter — awk traite automatiquement une clé non définie comme zéro ou comme une chaîne vide.
Compter les lignes par groupe
Le schéma d’agrégation le plus courant consiste à compter combien de fois chaque valeur unique d’un champ apparaît. Utilisez le champ $1 (ou n’importe quel autre champ) comme clé du tableau et incrémentez un compteur à chaque ligne correspondante.
Le bloc END s’exécute une fois toutes les données d’entrée consommées — c’est à cet endroit que vous affichez les résultats accumulés.
count[$1]++Après le traitement, count contient le nombre total de lignes pour chaque valeur unique de $1.
#!/usr/bin/env bash
# Count how many log entries exist per HTTP status code
# Input format: <ip> <date> <method> <path> <status> <bytes>
printf '10.0.0.1 2024-01-01 GET /index 200 512
10.0.0.2 2024-01-01 POST /api 404 128
10.0.0.3 2024-01-01 GET /img 200 2048
10.0.0.4 2024-01-01 GET /api 500 64
10.0.0.5 2024-01-01 DELETE /api 404 32
' | awk '
{
count[$5]++
}
END {
for (status in count)
print status, count[status]
}'
Additionner un champ numérique par groupe
Le comptage n’est qu’une forme d’agrégation. Pour calculer la somme d’un champ numérique regroupé selon un autre champ, accumulez la valeur numérique dans un tableau dont la clé est le champ de regroupement.
Le schéma est le suivant :
- Clé = le champ de regroupement (par exemple,
$1pour le nom d’utilisateur) - Valeur = le total cumulé du champ numérique (par exemple,
$2pour le nombre d’octets)
Cette méthode calcule une somme complète par groupe en une seule passe awk — aucun tri ni prétraitement n’est nécessaire.
#!/usr/bin/env bash
# Sum bytes transferred per user from an access log
printf 'alice 1024
bob 512
alice 2048
charlie 256
bob 768
alice 128
' | awk '
{
bytes[$1] += $2
}
END {
for (user in bytes)
printf "%-10s %d bytes\n", user, bytes[user]
}'
Combiner comptage et somme en une seule passe
awk vous permet de gérer plusieurs tableaux simultanément, ce qui vous donne le compte et la somme (et donc la moyenne) pour chaque groupe en un seul parcours du fichier. C’est bien plus efficace que d’exécuter la chaîne de traitement deux fois.
count[key]++— suit le nombre d’occurrencestotal[key] += $N— suit la somme cumulée- Dans
END, diviseztotal[k] / count[k]pour obtenir la moyenne par groupe
#!/usr/bin/env bash
# Compute per-department headcount and average salary
printf 'Engineering Alice 95000
Engineering Bob 88000
Marketing Carol 72000
Marketing Dave 68000
Engineering Eve 102000
Marketing Frank 75000
' | awk '
{
dept = $1
sal = $3
count[dept]++
total[dept] += sal
}
END {
printf "%-15s %5s %10s\n", "Department", "Count", "Avg Salary"
for (d in count)
printf "%-15s %5d %10.0f\n", d, count[d], total[d]/count[d]
}'
Clés à plusieurs champs pour un regroupement en 2 dimensions
Vous pouvez créer une clé composite en concaténant plusieurs champs avec un séparateur. Vous obtenez ainsi un regroupement en deux dimensions sans syntaxe particulière.
Choisissez un séparateur qui ne peut pas apparaître dans les données (par exemple, SUBSEP, le séparateur d’enregistrements awk intégré \034, ou une barre verticale littérale |).
- Clé composite :
arr[$1 SUBSEP $2]ouarr[$1"|"$2] - Reconstituer la clé lors de l’affichage :
split(key, parts, "|")
#!/usr/bin/env bash
# Count requests grouped by HTTP method AND status code
printf 'GET 200
POST 201
GET 404
GET 200
DELETE 204
POST 201
GET 404
POST 500
' | awk '
{
key = $1 "|" $2
count[key]++
}
END {
printf "%-8s %-6s %s\n", "Method", "Status", "Count"
for (k in count) {
split(k, parts, "|")
printf "%-8s %-6s %d\n", parts[1], parts[2], count[k]
}
}'
Suivre les minimums et maximums par groupe
Les tableaux associatifs facilitent le suivi des valeurs min et max par groupe. L’astuce consiste à initialiser uniquement lors de la première occurrence de chaque clé grâce à la condition spéciale !(key in arr).
!(key in min_arr)est vraie la première fois qu’une clé est rencontrée- Après l’initialisation, comparez puis remplacez avec la comparaison standard inférieur à / supérieur à
Ce schéma évite qu’un zéro parasite ne fausse votre minimum.
#!/usr/bin/env bash
# Find min and max response time per endpoint
printf '/api/users 120
/api/orders 340
/api/users 98
/api/orders 512
/api/users 210
/api/orders 280
/health 5
/health 7
' | awk '
{
ep = $1
rt = $2
if (!(ep in mn)) { mn[ep] = rt; mx[ep] = rt }
if (rt < mn[ep]) mn[ep] = rt
if (rt > mx[ep]) mx[ep] = rt
}
END {
printf "%-15s %6s %6s\n", "Endpoint", "Min", "Max"
for (ep in mn)
printf "%-15s %6d %6d\n", ep, mn[ep], mx[ep]
}'
Distribution des fréquences — groupes les plus fréquents
Une tâche courante dans les situations réelles consiste à trouver les valeurs les plus fréquentes, au nombre de N. awk s’occupe du comptage ; utilisez sort puis head pour classer et limiter les résultats.
Ce schéma de chaîne de traitement est caractéristique de l’ingénierie des scripts shell :
- awk compte les occurrences dans un tableau et affiche
count keydansEND sort -rneffectue un tri numérique décroissanthead -n 5ne conserve que les 5 premiers résultats
En laissant awk se concentrer sur l’agrégation et en déléguant le tri à sort, vous suivez la philosophie Unix.
#!/usr/bin/env bash
# Top 3 most active IP addresses from an access log
printf '192.168.1.10 GET /index
10.0.0.5 POST /api
192.168.1.10 GET /css
172.16.0.3 GET /index
10.0.0.5 GET /api
192.168.1.10 DELETE /api
172.16.0.3 POST /login
10.0.0.5 GET /index
10.0.0.5 POST /logout
' | awk '{count[$1]++} END {for (ip in count) print count[ip], ip}' \
| sort -rn \
| head -n 3
Utiliser NR et FNR pour agréger plusieurs fichiers
Lors du traitement de plusieurs fichiers, les variables intégrées NR (nombre total d’enregistrements lus) et FNR (nombre d’enregistrements dans le fichier actuel) vous permettent d’indiquer de quel fichier provient chaque enregistrement à l’aide de FILENAME.
FILENAME— nom du fichier en cours de lectureFNR == 1— se déclenche au début de chaque nouveau fichier (utile pour ignorer les en-têtes)
Cela permet d’effectuer une agrégation par fichier sur l’ensemble d’un répertoire de journaux en une seule invocation d’awk.
Afficher une sortie triée à partir de tableaux awk
La boucle for (key in array) d’awk ne garantit pas l’ordre. Pour obtenir une sortie déterministe, envoyez l’affichage du bloc END d’awk vers sort, ou rassemblez les valeurs et triez-les dans awk à l’aide des fonctions asorti / asort (GNU awk uniquement).
L’approche portable avec une chaîne de traitement shell est généralement privilégiée pour les scripts multiplateformes :
sort -k1,1— trie alphabétiquement selon le premier champ (la clé du groupe)sort -k2,2rn— trie numériquement par ordre décroissant selon le deuxième champ (le compte ou la somme)
#!/usr/bin/env bash
# Bytes per user, sorted alphabetically by username
printf 'zara 800
alice 1500
bob 300
alice 200
zara 400
bob 1100
' | awk '
{
total[$1] += $2
}
END {
for (u in total)
print u, total[u]
}' | sort -k1,1
Supprimer des clés de tableau et réinitialiser l’état
Vous devez parfois réinitialiser l’état de l’agrégation au milieu du flux — par exemple, lors du traitement de fichiers journaux où chaque section est séparée par une ligne vide ou une valeur sentinelle.
delete arr[key]— supprime une seule entréedelete arr— efface le tableau entier (GNU awk)- Vérifiez l’existence avec
(key in arr)avant d’y accéder afin d’éviter de créer des entrées fantômes
Cette technique permet d’effectuer une agrégation par fenêtre glissante ou par section sans redémarrer awk.
#!/usr/bin/env bash
# Sum values within each section delimited by "---"
printf 'alice 100
bob 200
---
alice 50
bob 75
charlie 300
---
' | awk '
/^---/ {
print "-- Section totals --"
for (u in total) printf " %-10s %d\n", u, total[u]
delete total
next
}
{
total[$1] += $2
}'
Chaîne de traitement réelle : résumé de journaux Nginx
Mettons tout cela en pratique : voici une agrégation awk de qualité production, effectuée en une seule passe sur un journal Nginx au format combiné. Elle calcule le nombre de requêtes, le nombre total d’octets et le taux d’erreur pour chaque hôte virtuel en un seul parcours.
Techniques clés utilisées :
- Clé composite :
vhostextrait d’un champ - Tableaux parallèles :
reqs[],bytes[],errors[] - Accumulation conditionnelle :
$9 >= 400pour ne compter que les réponses en erreur - Tableau mis en forme avec
printfdansEND
#!/usr/bin/env bash
# Simulated Nginx combined log: host ip - - [date] "METHOD /path HTTP/1.1" status bytes
printf 'api.example.com 10.0.0.1 - - [01/Jan/2024] "GET /v1" 200 1024
www.example.com 10.0.0.2 - - [01/Jan/2024] "GET /" 200 4096
api.example.com 10.0.0.3 - - [01/Jan/2024] "POST /v1" 500 128
www.example.com 10.0.0.4 - - [01/Jan/2024] "GET /img" 404 64
api.example.com 10.0.0.5 - - [01/Jan/2024] "GET /v1" 200 2048
www.example.com 10.0.0.6 - - [01/Jan/2024] "GET /" 200 4096
api.example.com 10.0.0.7 - - [01/Jan/2024] "DELETE /v1" 403 32
' | awk '
{
host = $1; status = $9; b = $10
reqs[host]++
bytes[host] += b
if (status + 0 >= 400) errors[host]++
}
END {
printf "%-20s %6s %10s %6s\n", "Host", "Reqs", "Bytes", "Errors"
for (h in reqs)
printf "%-20s %6d %10d %6d\n", h, reqs[h], bytes[h], errors[h]+0
}'
Vérification des connaissances : initialiser correctement le minimum
Vérifiez votre compréhension d’un piège courant de l’agrégation awk.
Récapitulatif de la leçon : agrégation avec les tableaux awk
Vous avez appris les principaux schémas permettant de calculer des agrégations par groupe entièrement dans awk :
- Comptage :
count[$key]++— incrémenter à chaque ligne, afficher dansEND - Somme :
total[$key] += $N— accumuler les champs numériques par groupe - Moyenne : conserver à la fois
count[]ettotal[], puis diviser dansEND - Minimum/maximum : initialiser à la première occurrence avec
!(key in arr), puis comparer - Clés composites : concaténer les champs avec un séparateur pour effectuer un regroupement multidimensionnel
- Sortie triée : envoyer l’affichage du bloc
ENDd’awk verssortpour obtenir un ordre déterministe - Réinitialisation des sections : utiliser
delete arrpour effacer l’état entre les sections logiques de l’entrée
Ces schémas vous permettent de remplacer de lourdes requêtes de base de données ou plusieurs passages dans une chaîne de traitement par une seule invocation awk efficace — une compétence essentielle pour l’ingénierie des scripts shell en production.
Questions Fréquemment Posées
La leçon « Agrégation avec les tableaux et le regroupement dans awk » est-elle gratuite ?
Oui — le texte complet de « Agrégation avec les tableaux et le regroupement dans awk » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Linux Command Line & Bash Scripting Mastery, passe à CoddyKit PRO. Le cours Linux Command Line & Bash Scripting Mastery comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Agrégation avec les tableaux et le regroupement dans awk » ?
Calculez des sommes, des décomptes et des synthèses par groupe à l’aide de tableaux associatifs indexés par les valeurs des champs. Tu pratiques Linux Command Line & Bash Scripting Mastery avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Linux Command Line & Bash Scripting Mastery ?
Aucune expérience préalable n'est requise. Linux Command Line & Bash Scripting Mastery sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Agrégation avec les tableaux et le regroupement dans awk » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Linux Command Line & Bash Scripting Mastery ?
Oui. Chaque leçon Linux Command Line & Bash Scripting Mastery inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Enregistrements, champs et séparateurs personnalisés dans awk
- Motifs, plages et blocs BEGIN/END
- Agrégation avec les tableaux et le regroupement dans awk
- Fonctions awk, mise en forme avec printf et génération de rapports