DevOps-bootcamp · leksjon

Aggregering med awk-tabeller og gruppering

Beregn summer, antall og gruppevise sammendrag ved hjelp av assosiative tabeller med feltverdier som nøkler.

Leksjon 3 av 413 trinn

Aggregering med awk-tabeller og gruppering er en gratis leksjon i DevOps-bootcamp på CoddyKit. Dette er leksjon 3 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i DevOps-bootcamp, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i DevOps-bootcamp 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 matrise­nø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 $1 for brukernavn)
  • Verdi = løpende total for det numeriske feltet (for eksempel $2 for 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 forekomster
  • total[key] += $N — holder oversikt over den løpende summen
  • I END deler du total[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] eller arr[$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:

  1. awk teller forekomster i en matrise og skriver ut count key i END
  2. sort -rn sorterer numerisk i synkende rekkefølge
  3. head -n 5 beholder 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 matrise­nø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øring
  • delete 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: vhost hentet fra et felt
  • Parallelle matriser: reqs[], bytes[], errors[]
  • Betinget akkumulering: $9 >= 400 for å telle bare feilsvar
  • Formatert printf-tabell i END
#!/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 i END
  • Summering: total[$key] += $N — akkumuler numeriske felt per gruppe
  • Gjennomsnitt: vedlikehold både count[] og total[], og divider i END
  • 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 gjennom sort for en deterministisk rekkefølge
  • Tilbakestilling av seksjoner: bruk delete arr for å 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.

Gratis å komme i gang

Lær deg DevOps-bootcamp 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
142
Leksjoner
568

Ofte stilte spørsmål

Er leksjonen «Aggregering med awk-tabeller og gruppering» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien DevOps-bootcamp, inkludert «Aggregering med awk-tabeller og gruppering», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i DevOps-bootcamp 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å DevOps-bootcamp 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 DevOps-bootcamp?

Ingen tidligere erfaring er nødvendig. DevOps-bootcamp 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 DevOps-bootcamp-leksjonen?

Ja. Alle DevOps-bootcamp-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

  1. Poster, felt og egendefinerte skilletegn i awk
  2. Mønstre, områder og BEGIN/END-blokker
  3. Aggregering med awk-tabeller og gruppering
  4. awk-funksjoner, printf-formatering og rapportgenerering
← Tilbake til DevOps-bootcamp