Poster, felter og brugerdefinerede separatorer i awk
Styr input- og outputseparatorer for felter, så De kan opdele CSV-, TSV- og loglinjer i rene kolonner.
Poster, felter og brugerdefinerede separatorer i awk er en gratis Intensiv DevOps-uddannelse-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Intensiv DevOps-uddannelse, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Intensiv DevOps-uddannelse-kurset indeholder 4 lektioner i alt.
Hvad er poster og felter i awk?
awk læser input linje for linje. Hver linje kaldes en post, og hvert whitespace-adskilt stykke på linjen kaldes et felt.
$0— den aktuelle post i sin helhed (hele linjen)$1— det første felt$2— det andet felt$NF— det sidste felt (NF= antal felter)
Som standard opdeler awk felter ved enhver sammenhængende sekvens af whitespace (mellemrum eller tabulatorer). Det gør awk straks nyttig til fortolkning af logning, kommandouddata og mellemrumsafgrænsede data.
#!/usr/bin/env bash
# Show how awk sees records and fields
echo 'alice 30 engineer' | awk '{ print "Name:", $1, "Age:", $2, "Role:", $3 }'
# $NF is always the last field — regardless of how many there are
echo 'one two three four five' | awk '{ print "Last field:", $NF }'Inputfeltseparatoren: FS
Den indbyggede variabel FS (feltseparator) fortæller awk, hvordan hver post skal opdeles i felter. Standardværdien er ét enkelt mellemrum, som aktiverer tilstanden for opdeling ved whitespace.
Du kan angive FS på to måder:
- Med flaget
-Fpå kommandolinjen:awk -F':' - Inde i en
BEGIN-blok:BEGIN { FS = ":" }
Begge metoder er ækvivalente. Tilgangen med en BEGIN-blok foretrækkes i længere scripts, fordi konfigurationen forbliver inde i selve scriptet, hvilket gør det mere læsbart og portabelt.
#!/usr/bin/env bash
# Parse /etc/passwd using ':' as the field separator
# Field 1 = username, field 3 = UID, field 7 = shell
echo 'root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin' \
| awk -F':' '{ print $1, "UID="$3, "shell="$7 }'Angivelse af FS i BEGIN-blokken
For scripts, der er længere end én linje, er det standardpraksis at placere FS i en BEGIN-blok. BEGIN-blokken kører før awk læser input, så separatoren er klar til den første post.
Dette mønster lader dig også angive flere variabler på én gang, tilføje kommentarer og holde logikken samlet i en scriptfil.
Almindelige separatorer, du vil møde i praksis:
- Kolon
:—/etc/passwd,/etc/shadow - Tabulator
\t— TSV-eksporter, compileroutput - Komma
,— CSV-filer (enkle, uden citerede felter) - Pipe
|— nogle logformater, databaseudtræk
#!/usr/bin/env bash
# awk script using BEGIN to set FS for TSV input
printf 'alice\t30\tengineer\nbob\t25\tdesigner\ncarol\t35\tmanager\n' \
| awk 'BEGIN { FS = "\t" } { printf "%-10s age=%-3s role=%s\n", $1, $2, $3 }'Fortolkning af CSV-filer med awk
CSV (kommaseparerede værdier) er et af de mest almindelige dataformater inden for shelludvikling. Hvis du angiver FS=",", behandler awk kommaer som afgrænsere.
Vigtig begrænsning: awks indbyggede CSV-håndtering tager ikke højde for citerede felter, der indeholder kommaer (f.eks. "Smith, John"). For enkle CSV-filer uden citerede kommaer fungerer dette perfekt. Til CSV-filer, der overholder RFC 4180 og indeholder citerede felter, skal du bruge en rigtig CSV-fortolker eller miller/csvkit.
En almindelig opgave fra virkeligheden er at udtrække bestemte kolonner og filtrere rækker efter værdi — begge dele er trivielt med awk, når FS er angivet.
#!/usr/bin/env bash
# Simple CSV: extract name and salary columns, filter salary > 50000
data='name,department,salary
alice,engineering,95000
bob,marketing,48000
carol,engineering,112000
dave,hr,45000'
echo "$data" | awk -F',' '
NR == 1 { next } # skip header row
$3 > 50000 { print $1, "earns", $3 }
'Feltseparatorer med flere tegn og regulære udtryk
awks FS er ikke begrænset til ét enkelt tegn — den kan være et regulært udtryk. Det er nyttigt til virkelige logformater, hvor felter adskilles af afgrænsere med variabel længde.
Eksempler på separatorer som regulære udtryk:
FS = "[,;]"— opdel ved enten komma eller semikolonFS = "[ \t]+"— opdel ved ét eller flere mellemrum eller tabulatorer (samme som standarden, men eksplicit)FS = "::"— opdel ved et bogstaveligt dobbeltkolonFS = "\\|"— opdel ved et pipe-tegn (skal escapes)
Når FS er et regulært udtryk, behandler awk (gawk) det som et mønster og ikke som en bogstavelig streng.
#!/usr/bin/env bash
# Log lines with mixed delimiters: split on " | " or "::" or ","
# Here we split on one or more spaces or pipe characters
printf '2024-01-15 | ERROR | disk full | /dev/sda1\n2024-01-15 | INFO | startup ok | main\n' \
| awk -F' \\| ' '{ printf "date=%-12s level=%-6s msg=%s\n", $1, $2, $3 }'
# Split on multiple possible delimiters using character class
echo 'alpha,beta;gamma,delta;epsilon' \
| awk -F'[,;]' '{ for(i=1; i<=NF; i++) print i": "$i }'Outputfeltseparatoren: OFS
OFS (outputfeltseparator) styrer, hvad awk placerer mellem felter, når du gendanner en post med print. Standardværdien er ét enkelt mellemrum.
Den vigtige pointe er, at OFS kun indsættes mellem felter, når du bruger komma-syntaks i print, eller når du tildeler en værdi til et felt, så awk genopbygger $0. Hvis du sammenkæder med mellemrum i kildekoden, bruges OFS ikke.
print $1, $2, $3— kommaer udløser OFS mellem felterneprint $1 " " $2— eksplicit mellemrum, OFS ignoreres
Et almindeligt mønster er at læse CSV, transformere dataene og skrive TSV ved at angive FS="," og OFS="\t".
#!/usr/bin/env bash
# Convert CSV to TSV using FS and OFS
data='alice,30,engineer
bob,25,designer
carol,35,manager'
echo "$data" | awk 'BEGIN { FS=","; OFS="\t" } { print $1, $2, $3 }'
echo '---'
# OFS also applies when you modify a field — awk rebuilds $0 with OFS
echo 'alice,30,engineer' | awk 'BEGIN { FS=","; OFS=" | " } { $1=$1; print $0 }'Tving awk til at genopbygge $0 med OFS
Der findes et subtilt, men vigtigt trick: Hvis du tildeler en værdi til et felt (selv tildeler et felt dets egen værdi, $1=$1), tvinger du awk til at genopbygge $0 ved at forbinde alle felter med OFS.
Dette er den idiomatiske måde at omformatere en posts afgrænsere på uden manuelt at udskrive hvert felt:
- Angiv
FStil inputafgrænseren - Angiv
OFStil den ønskede outputafgrænser - Udløs en genopbygning med
$1=$1 - Udskriv
$0
Tilgangen skalerer til et vilkårligt antal felter og undgår hårdkodning af $1, $2, $3, ....
#!/usr/bin/env bash
# Reformat a pipe-delimited file to comma-separated WITHOUT listing every field
printf 'alice|30|engineer|london\nbob|25|designer|paris\ncarol|35|manager|berlin\n' \
| awk 'BEGIN { FS="|"; OFS="," } { $1=$1; print $0 }'
# Useful when you don't know how many fields there are:
printf 'a|b|c|d|e|f|g\n1|2|3|4|5|6|7\n' \
| awk 'BEGIN { FS="|"; OFS="\t" } { $1=$1; print $0 }'Postseparatoren: RS
Ligesom FS opdeler felter i en post, definerer RS (postseparatoren), hvad der adskiller poster fra hinanden. Som standard er RS et linjeskift, så awk behandler én linje ad gangen.
Hvis du ændrer RS, får du adgang til effektiv behandling af poster over flere linjer:
RS=""— afsnitstilstand: tomme linjer adskiller poster (felter kan strække sig over flere linjer)RS=";"— opdeler ved semikoloner (nyttigt til SQL-dumps)RS="\n"— eksplicit linjeskift (standardværdien)
I afsnitstilstand (RS="") bruges FS stadig til at opdele felter i den flerliniære post, og linjeskift i en post behandles også automatisk som feltseparatorer.
#!/usr/bin/env bash
# Paragraph mode: each blank-line-separated block is one record
# Useful for processing structured text blocks (e.g., stanzas, config sections)
data='Name: Alice
Role: Engineer
City: London
Name: Bob
Role: Designer
City: Paris'
echo "$data" | awk 'BEGIN { RS=""; FS="\n" } {
print "Record", NR":"
for (i=1; i<=NF; i++) print " ", $i
print ""
}'Outputpostseparatoren: ORS
ORS (outputpostseparatoren) udskrives efter hver print-instruktion. Som standard er den et linjeskift (\n), hvilket er grunden til, at hver print skriver på en ny linje.
Hvis du ændrer ORS, kan du:
- Samle poster på én linje:
ORS=" " - Tilføje tomme linjer mellem outputposter:
ORS="\n\n" - Oprette brugerdefinerede outputformater som JSON- eller XML-fragmenter
Bemærk, at printf ikke bruger ORS — den gælder kun for den ubetingede print-instruktion. Brug printf, når du har brug for fuld kontrol over formateringen.
#!/usr/bin/env bash
# Join all matching lines onto one line by setting ORS to a space
printf 'apple\nbanana\ncherry\ndate\n' | awk '{ ORS=" " } { print $0 }'
echo # final newline
# Add a blank line after every output record for readability
printf 'alice 30 engineer\nbob 25 designer\ncarol 35 manager\n' \
| awk 'BEGIN { ORS="\n\n" } { print $1, "is a", $3 }'Praktisk eksempel: Fortolkning af Apache-adgangslogge
Apache-/nginx-adgangslogge har et velkendt format med felter adskilt af mellemrum. Nogle felter (f.eks. tidsstemplet) indeholder mellemrum og er omgivet af kantede parenteser eller anførselstegn — derfor kan direkte feltopdeling med awk være vanskelig.
En praktisk tilgang er at bruge en regulært udtryksbaseret FS, der tager højde for strukturen, eller at udtrække bestemte felter efter position, når du kender det nøjagtige format.
Felterne i Combined Log Format er omtrent:
- Klient-IP
- Ident (normalt
-) - Godkendelsesbruger (normalt
-) - Tidsstempel (i kantede parenteser, tæller som ét token)
- Anmodningsmetode+sti+protokol (i anførselstegn)
- HTTP-statuskode
- Svarbytes
#!/usr/bin/env bash
# Parse a simulated Apache Combined Log Format line
# Extract: IP, status code, bytes, and request path
logs='192.168.1.10 - alice [15/Jan/2024:10:23:45 +0000] "GET /api/users HTTP/1.1" 200 1523
10.0.0.5 - - [15/Jan/2024:10:23:46 +0000] "POST /login HTTP/1.1" 401 89
172.16.0.3 - bob [15/Jan/2024:10:23:47 +0000] "GET /dashboard HTTP/1.1" 200 8741'
echo "$logs" | awk '{
ip = $1
status = $9
bytes = $10
# Extract the request path from the quoted string in field 7
split($7, parts, "/")
path = "/" parts[2]
printf "ip=%-15s status=%s bytes=%-6s endpoint=%s\n", ip, status, bytes, path
}'Kombination af FS, OFS, RS og ORS i en pipeline
I praktisk shell-udvikling bruger du sjældent disse separatorer isoleret. Et almindeligt pipelinemønster er at bruge awk som en formatkonverter midt i en pipeline, hvor ét struktureret format omdannes til et andet.
Vigtige pointer ved kombination af separatorer:
- Indstil altid
FSogOFSsammen iBEGIN, når du konverterer formater - Brug
$1=$1til at udløse en genopbygning af$0, når du vil formatere alle felter igen uden at angive dem enkeltvis - Skift kun
RS, når dine poster reelt strækker sig over flere linjer - Brug
ORStil at styre afstanden mellem outputposter - Foretræk
printftil præcis formatering; brugprint, når den automatiske afslutning medORSer praktisk
#!/usr/bin/env bash
# Full pipeline: read a colon-delimited file,
# filter rows where field 3 (UID) >= 1000 (real users),
# then output as tab-separated: username, UID, home dir
echo 'root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
alice:x:1001:1001:Alice:/home/alice:/bin/bash
bob:x:1002:1002:Bob:/home/bob:/bin/zsh
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin' \
| awk 'BEGIN { FS=":"; OFS="\t" } $3 >= 1000 { print $1, $3, $6 }'Videnstjek: OFS og genopbygning af felter
Test din forståelse af, hvordan OFS fungerer sammen med felttildeling i awk.
Opsummering af lektionen: Poster, felter og separatorer
Du har nu fuld kontrol over, hvordan awk læser og skriver strukturerede data. Her er en opsummering af de fire separatorvariabler:
FS— inputfeltseparator. Indstilles med-Feller iBEGIN. Kan være et tegn, en streng eller et regulært udtryk. Standard: blanktegn.OFS— outputfeltseparator. Indsættes mellem felter i kald somprint $1, $2og når awk genopbygger$0efter en felttildeling. Standard: ét mellemrum.RS— inputpostseparator. Definerer, hvad der adskiller poster (linjer). Standard: linjeskift. Sæt den til en tom streng for afsnitstilstand.ORS— outputpostseparator. Tilføjes efter hverprint. Standard: linjeskift. Skift den for at samle linjer eller tilføje afstand.
Det vigtigste mønster at huske er: Indstil både FS og OFS i BEGIN, og brug derefter $1=$1 til at genopbygge $0, når du vil omformatere separatorer på tværs af alle felter uden at hardkode feltpositioner. Dette mønster fungerer for filer med et vilkårligt antal kolonner og er grundlaget for awk-baserede formatkonverteringspipelines.
Lær Intensiv DevOps-uddannelse med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 142
- Lektioner
- 568
Ofte stillede spørgsmål
Er lektionen “Poster, felter og brugerdefinerede separatorer i awk” gratis?
Ja — alle 3 lektioner i læringssporet Intensiv DevOps-uddannelse, inklusive “Poster, felter og brugerdefinerede separatorer i awk”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Intensiv DevOps-uddannelse-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Poster, felter og brugerdefinerede separatorer i awk”?
Styr input- og outputseparatorer for felter, så De kan opdele CSV-, TSV- og loglinjer i rene kolonner. Du øver dig i Intensiv DevOps-uddannelse med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Intensiv DevOps-uddannelse?
Der kræves ingen tidligere erfaring. Intensiv DevOps-uddannelse på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.
Hvor lang tid tager lektionen “Poster, felter og brugerdefinerede separatorer i awk”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Intensiv DevOps-uddannelse-lektion?
Ja. Alle Intensiv DevOps-uddannelse-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Poster, felter og brugerdefinerede separatorer i awk
- Mønstre, områder og BEGIN/END-blokke
- Aggregering med awk-arrays og gruppering
- awk-funktioner, printf-formatering og rapportgenerering