Aggregering med awk-tabeller og gruppering
Beregn summer, antall og gruppevise sammendrag ved hjelp av assosiative tabeller med feltverdier som nøkler.
Aggregering med awk-tabeller og gruppering er en gratis leksjon i Mestring av Linux-kommandolinjen og Bash-skripting på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Mestring av Linux-kommandolinjen og Bash-skripting, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Mestring av Linux-kommandolinjen og Bash-skripting inneholder totalt 4 leksjoner.
Hva er assosiative matriser i awk
I awk er en assosiativ matrise en nøkkel-verdi-lagring der nøklene kan være en hvilken som helst streng eller et tall. I motsetning til indekserte matriser i de fleste språk er matriser i awk egentlig hash-tabeller — perfekt for å gruppere og aggregere data etter feltverdier.
- Deklareres implisitt: tilordne ganske enkelt
arr[key] = value - Nøkler er strenger som standard (tall konverteres)
- Ingen størrelsesbegrensning — awk utvider matrisen etter behov
- Ideelt for å beregne summer, antall og gruppevise oppsummeringer i én gjennomgang
Du trenger ikke å initialisere en nøkkel før du øker den — awk behandler automatisk en nøkkel som ikke er satt, som null eller en tom streng.
Telle linjer per gruppe
Det vanligste aggregeringsmønsteret er å telle hvor mange ganger hver unike verdi i et felt forekommer. Bruk feltet $1 (eller et hvilket som helst annet felt) som matrisenøkkel, og øk en teller for hver rad som samsvarer.
END-blokken kjøres etter at all input er lest — det er der du skriver ut de akkumulerte resultatene.
count[$1]++Etter behandlingen inneholder count det totale antallet linjer for hver unike verdi av $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]
}'
Summere et numerisk felt per gruppe
Å telle er bare én form for aggregering. Hvis du vil summere et numerisk felt gruppert etter et annet felt, akkumulerer du den numeriske verdien i en matrise som er nøkkelbestemt av gruppefeltet.
Mønsteret er:
- Nøkkel = feltet det grupperes etter (for eksempel
$1for brukernavn) - Verdi = løpende total for det numeriske feltet (for eksempel
$2for byte)
Dette beregner en full gruppevis sum i én awk-gjennomgang — ingen sortering eller forhåndsbehandling er nødvendig.
#!/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]
}'
Kombinere antall og sum i én gjennomgang
awk lar deg vedlikeholde flere matriser samtidig, slik at du får antall og sum (og dermed gjennomsnitt) for hver gruppe i én gjennomgang av filen. Dette er langt mer effektivt enn å kjøre rørledningen to ganger.
count[key]++— holder oversikt over forekomstertotal[key] += $N— holder oversikt over den løpende summen- I
ENDdeler dutotal[k] / count[k]for å finne gjennomsnittet per gruppe
#!/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]
}'
Flerfeltsnøkler for todimensjonal gruppering
Du kan opprette en sammensatt nøkkel ved å sette sammen flere felt med et skilletegn. Dette gir deg en todimensjonal gruppering uten spesiell syntaks.
Velg et skilletegn som ikke kan forekomme i dataene (for eksempel SUBSEP, det innebygde awk-postskilletegnet \034, eller en bokstavelig loddrett strek |).
- Sammensatt nøkkel:
arr[$1 SUBSEP $2]ellerarr[$1"|"$2] - Del nøkkelen opp igjen ved utskrift:
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]
}
}'
Holde oversikt over minimum og maksimum per gruppe
Assosiative matriser gjør det enkelt å holde oversikt over min- og max-verdier per gruppe. Trikset er å initialisere bare første gang hver nøkkel forekommer, ved hjelp av den spesielle betingelsen !(key in arr).
!(key in min_arr)er sann første gang en nøkkel registreres- Etter initialiseringen sammenligner du og overskriver med den vanlige testen for mindre enn / større enn
Dette mønsteret unngår en misvisende nullverdi som ellers ville ødelagt minimumsverdien.
#!/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]
}'
Frekvensfordeling — topp N-grupper
En vanlig oppgave i praksis er å finne de N mest frekvente verdiene. awk håndterer opptellingen; send resultatet gjennom sort og head for å rangere og begrense det.
Dette rørledningsmønsteret er idiomatisk i skallprogrammering:
- awk teller forekomster i en matrise og skriver ut
count keyiEND sort -rnsorterer numerisk i synkende rekkefølgehead -n 5beholder bare de fem øverste
Ved å la awk fokusere på aggregering og overlate sorteringen til sort følger du Unix-filosofien.
#!/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
Bruke NR og FNR til aggregering fra flere filer
Når du behandler flere filer, lar awks innebygde NR (totalt antall leste poster) og FNR (antall poster i gjeldende fil) deg merke hvilken fil hver post kom fra ved hjelp av FILENAME.
FILENAME— navnet på filen som leses nåFNR == 1— utløses ved starten av hver nye fil (nyttig for å hoppe over overskrifter)
Dette gjør det mulig å aggregere grupper per fil på tvers av en hel katalog med logger i én awk-kjøring.
Skrive ut sorterte resultater fra awk-matriser
for (key in array)-løkken i awk garanterer ikke rekkefølgen. For deterministiske resultater kan du sende awks END-utskrift gjennom sort, eller samle inn verdier og sortere dem i awk ved hjelp av funksjonene asorti / asort (bare GNU awk).
Den portable tilnærmingen med en skallrørledning foretrekkes vanligvis for skript på tvers av plattformer:
sort -k1,1— sorter alfabetisk etter det første feltet (gruppenøkkelen)sort -k2,2rn— sorter numerisk etter det andre feltet (antall/sum) i synkende rekkefølge
#!/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
Slette matrisenøkler og tilbakestille tilstanden
Noen ganger må du tilbakestille aggregeringstilstanden underveis — for eksempel når du behandler loggfiler der hver seksjon er skilt med en tom linje eller en markørverdi.
delete arr[key]— fjerner én oppføringdelete arr— tømmer hele matrisen (GNU awk)- Kontroller om nøkkelen finnes med
(key in arr)før du bruker den, for å unngå å opprette spøkelsesoppføringer
Denne teknikken gjør det mulig å aggregere med glidende vindu eller per seksjon uten å starte awk på nytt.
#!/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
}'
Praktisk rørledning: sammendrag av Nginx-logger
Her setter vi alt sammen — en produksjonsklar awk-aggregering i én gjennomgang av et Nginx-format med kombinerte logger. Den beregner antall forespørsler, totalt antall byte og feilrate per virtuell vert i én gjennomgang.
Viktige teknikker:
- Sammensatt nøkkel:
vhosthentet fra et felt - Parallelle matriser:
reqs[],bytes[],errors[] - Betinget akkumulering:
$9 >= 400for å telle bare feilsvar - Formatert
printf-tabell iEND
#!/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
}'
Kunnskapssjekk: Initialisere minimum korrekt
Test forståelsen din av en vanlig fallgruve ved aggregering i awk.
Oppsummering av leksjonen: Aggregering med awk-matriser
Du har lært de grunnleggende mønstrene for å beregne gruppevise aggregeringer helt i awk:
- Opptelling:
count[$key]++— øk for hver rad, og skriv ut iEND - Summering:
total[$key] += $N— akkumuler numeriske felt per gruppe - Gjennomsnitt: vedlikehold både
count[]ogtotal[], og divider iEND - Min/maks: initialiser ved første forekomst med
!(key in arr), og sammenlign deretter - Sammensatte nøkler: sett sammen felt med et skilletegn for flerdimensjonal gruppering
- Sortert resultat: send awks
END-utskrift gjennomsortfor en deterministisk rekkefølge - Tilbakestilling av seksjoner: bruk
delete arrfor å tømme tilstanden mellom logiske seksjoner i inputen
Med disse mønstrene kan du erstatte tunge databasespørringer eller flere rørledningsgjennomganger med én effektiv awk-kjøring — en viktig ferdighet innen produksjonsrettet skallprogrammering.
Lær deg Bash med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 22
- Leksjoner
- 88
Ofte stilte spørsmål
Er leksjonen «Aggregering med awk-tabeller og gruppering» gratis?
Ja – hele teksten i «Aggregering med awk-tabeller og gruppering» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Mestring av Linux-kommandolinjen og Bash-skripting-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Mestring av Linux-kommandolinjen og Bash-skripting inneholder totalt 4 leksjoner.
Hva lærer jeg i «Aggregering med awk-tabeller og gruppering»?
Beregn summer, antall og gruppevise sammendrag ved hjelp av assosiative tabeller med feltverdier som nøkler. Du øver på Mestring av Linux-kommandolinjen og Bash-skripting med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Mestring av Linux-kommandolinjen og Bash-skripting?
Ingen tidligere erfaring er nødvendig. Mestring av Linux-kommandolinjen og Bash-skripting på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.
Hvor lang tid tar leksjonen «Aggregering med awk-tabeller og gruppering»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Mestring av Linux-kommandolinjen og Bash-skripting-leksjonen?
Ja. Alle Mestring av Linux-kommandolinjen og Bash-skripting-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Poster, felt og egendefinerte skilletegn i awk
- Mønstre, områder og BEGIN/END-blokker
- Aggregering med awk-tabeller og gruppering
- awk-funksjoner, printf-formatering og rapportgenerering