awk-commando: velden tonen, scheidingsteken -F en voorwaardelijke patronen

TestomgevingRHEL-familieAlmaLinux 9.8root-accountGecontroleerd op 2026-10-29

Het awk-commando is een Linux-hulpmiddel dat een tekstbestand regel voor regel leest, elke regel op spaties of een scheidingsteken dat je opgeeft in velden verdeelt, en alleen de velden van regels die aan een voorwaarde voldoen toont of ermee rekent. Op een AlmaLinux 9-server hebben we uit een voorbeeldbestand met het toegangslog van een webserver het aantal verzoeken per IP-adres en per statuscode geteld met één regel die via een pipe aan sort is gekoppeld: alle drie de 404-antwoorden in de twaalf regels waren verzoeken naar wp-login.php en .env vanaf één IP-adres.

De onderstaande uitvoer is verkregen met het root-account in een werkmap op een AlmaLinux 9.8-server. Het toegangslog, de accountlijst, de verkoopgegevens en het scorebestand zijn voorbeeldbestanden voor de test, en de IP-adressen en accountnamen daarin zijn ook voorbeeldwaarden.

1️⃣ Basisgebruik van het awk-commando

  • ↪️ Veldnummers en print

awk splitst elke gelezen regel op spaties en nummert de velden van voren af als $1, $2, $3. We hebben dit gecontroleerd met scores.txt, waarin naam, resultaat en score door spaties zijn gescheiden.

cat scores.txt
alice   pass  82
bob     fail  47
carol   pass  91
dave    pass  68
erin    fail  55

De accolades binnen de enkele aanhalingstekens bevatten de actie die op elke regel wordt uitgevoerd, en als je na print veldnummers met komma's opsomt, verschijnen alleen die velden. Toon je het eerste en derde veld, dan blijven alleen naam en score over.

awk '{print $1, $3}' scores.txt
alice 82
bob 47
carol 91
dave 68
erin 55

Laat je de komma tussen de velden weg en schrijf je $1 $3, dan lopen de twee waarden zonder spatie in elkaar over. De komma in print voegt het uitvoerscheidingsteken in (standaard één spatie), en waarden zonder komma worden aan elkaar geplakt tot één tekenreeks.

awk '{print $1 $3}' scores.txt
alice82
bob47
carol91
dave68
erin55

NR is het nummer van de tot nu toe gelezen regel, NF het aantal velden op die regel. $NF betekent het laatste veld, dus je kunt de laatste kolom kiezen, ook als het aantal velden per regel verschilt.

awk '{print NR, NF, $NF}' scores.txt
1 3 82
2 3 47
3 3 91
4 3 68
5 3 55

Ook het toegangslog van een webserver is met spaties gescheiden, dus je kiest velden op dezelfde manier. De veldnummers van de eerste regel van het testlog zijn als volgt.

VeldWaarde op de eerste regelBetekenis
$1192.0.2.10Client-IP
$4[29/Oct/2026:00:01:12Datum en tijd van het verzoek
$6"GETVerzoekmethode (met een dubbel aanhalingsteken ervoor)
$7/index.htmlVerzoek-URL
$9200Statuscode
$105120Verzonden bytes
$11"-"Vorige pagina (Referer)
$12~$15"Mozilla/5.0 (X11; Linux x86_64)"User-agent (gesplitst bij elke spatie)

We hebben $1, $7 en $9 getoond, oftewel het client-IP, de verzoek-URL en de statuscode.

awk '{print $1, $7, $9}' access.log
192.0.2.10 /index.html 200
198.51.100.7 /about.html 200
192.0.2.10 /images/logo.png 200
203.0.113.25 /wp-login.php 404
203.0.113.25 /wp-login.php 404
192.0.2.10 /contact.html 200
198.51.100.7 /old-page.html 301
203.0.113.25 /.env 404
192.0.2.44 /index.html 200
198.51.100.7 /api/search?q=awk 500
192.0.2.44 /images/logo.png 304
192.0.2.10 /index.html 200

Een kolom met spaties in de waarde, zoals de user-agent, wordt in meerdere velden gesplitst. NF was op alle eerste drie regels 15, en $NF is het laatste stuk van de user-agent.

awk '{print NF, $NF}' access.log | head -3
15 x86_64)"
15 x86_64)"
15 x86_64)"

2️⃣ Scheidingsteken instellen met awk -F

  • ↪️ Dubbele punt, komma en reguliere expressie als scheidingsteken

Bij een bestand waarvan de kolommen niet met spaties zijn gescheiden, schrijf je dat teken achter -F. Toen we $1 zonder -F toonden uit de accountlijst users.txt, die dezelfde vorm heeft als /etc/passwd, kwamen de meeste regels in hun geheel terug.

awk '{print $1}' users.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
nobody:x:65534:65534:Kernel
user:x:1000:1000:Example
deploy:x:1001:1001:Deploy
backup:x:1002:1002::/home/backup:/sbin/nologin

Het standaardscheidingsteken is de spatie, dus een regel die alleen met dubbele punten is verbonden, heeft maar één veld. Alleen de regels nobody, user en deploy, met een spatie in de beschrijvingskolom, worden bij die spatie gesplitst.

Met -F: als dubbelepunt-scheidingsteken worden accountnaam ($1) en loginshell ($7) gescheiden.

awk -F: '{print $1, $7}' users.txt
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
nobody /sbin/nologin
user /bin/bash
deploy /bin/bash
backup /sbin/nologin

Kommagescheiden CSV-bestanden splits je met -F,. Als je artikel en aantal uit de verkoopgegevens sales.csv toont, wordt de kop op de eerste regel (item qty) op dezelfde manier gesplitst en verschijnt die ook.

awk -F, '{print $2, $3}' sales.csv
item qty
keyboard 2
mouse 5
monitor 1
keyboard 1
cable 10
mouse 2
monitor 2

-F, past niet bij CSV-bestanden met komma's in kolommen tussen dubbele aanhalingstekens. In quoted.csv, met komma's in de artikelkolom, worden velden ook bij de komma's binnen de aanhalingstekens gesplitst, zodat in het tweede veld alleen het eerste deel van de artikelnaam overblijft.

awk -F, '{print $2}' quoted.csv
item
"cable
keyboard

Voor zulke bestanden beschrijft de officiële GNU Awk-handleiding de variabele FPAT. Schrijf je in plaats van een scheidingsteken de vorm van één veld als reguliere expressie, dan wordt een kolom tussen aanhalingstekens één veld.

awk -v FPAT='([^,]*)|("[^"]*")' '{print $2}' quoted.csv
item
"cable, usb"
keyboard

Wil je meerdere scheidingstekens, schrijf ze dan als reguliere expressie tussen vierkante haken. Met zowel de dubbele punt als de slash als scheidingsteken wordt $NF de laatste naam in het pad van de loginshell (bash, nologin).

awk -F'[:/]' '{print $1, $NF}' users.txt
root bash
bin nologin
daemon nologin
nobody nologin
user bash
deploy bash
backup nologin

3️⃣ Voorwaardelijke patronen van het awk-commando

  • ↪️ Reguliere expressies, vergelijkingen en NR

Ook als je velden kiest, worden alle regels getoond. Om alleen de nodige regels te houden, zet je een voorwaarde (patroon) vóór de accolades. Een tekenreeks tussen slashes selecteert alleen de regels die hem bevatten, en zonder actie wordt de hele regel getoond.

awk '/wp-login/' access.log
203.0.113.25 - - [29/Oct/2026:00:04:51 +0000] "POST /wp-login.php HTTP/1.1" 404 196 "-" "Mozilla/5.0 (X11; Linux x86_64)"
203.0.113.25 - - [29/Oct/2026:00:04:52 +0000] "POST /wp-login.php HTTP/1.1" 404 196 "-" "Mozilla/5.0 (X11; Linux x86_64)"

De geselecteerde regels zijn dezelfde als met het grep-commando, en awk kan uit die regels meteen de velden kiezen en tonen. Geef je dezelfde twee met grep geselecteerde regels via een pipe aan awk door, dan blijven alleen IP en statuscode over.

grep wp-login access.log | awk '{print $1, $9}'
203.0.113.25 404
203.0.113.25 404

Veldwaarden vergelijk je met ==, !=, >, >=, <, <=. We hebben alleen de regels met statuscode ($9) 404 geselecteerd en het IP en de verzoek-URL getoond.

awk '$9 == 404 {print $1, $7}' access.log
203.0.113.25 /wp-login.php
203.0.113.25 /wp-login.php
203.0.113.25 /.env

Bij vergelijking met een tekenreeks zet je de waarde tussen dubbele aanhalingstekens. We hebben alleen de namen geselecteerd waarvan het tweede veld pass is.

awk '$2 == "pass" {print $1}' scores.txt
alice
carol
dave

Numerieke vergelijkingen gebruik je om op bereik te selecteren, zoals bij accountnummers (UID's). Selecteer je accounts met een UID van 1000 of hoger, dan zit naast de gewone accounts ook nobody met UID 65534 erbij.

awk -F: '$3 >= 1000 {print $1, $3}' users.txt
nobody 65534
user 1000
deploy 1001
backup 1002

Twee voorwaarden combineer je met &&. Voeg je de voorwaarde onder 65534 toe, dan valt nobody weg en blijven alleen de drie gewone accounts en hun thuismappen over.

awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $6}' users.txt
user /home/user
deploy /home/deploy
backup /home/backup

[~] controleert of een veld overeenkomt met een reguliere expressie, [!~] of dat niet zo is. Selecteer je accounts waarvan de loginshell ($7) op bash eindigt en accounts waarvan die niet nologin is, dan krijg je dezelfde drie accounts.

awk -F: '$7 ~ /bash$/ {print $1}' users.txt
root
user
deploy
awk -F: '$7 !~ /nologin/ {print $1, $7}' users.txt
root /bin/bash
user /bin/bash
deploy /bin/bash

Een NR-voorwaarde selecteert op regelnummer. NR > 1 haalt de CSV-kopregel weg, zodat alleen de verkoopgegevens overblijven.

awk -F, 'NR > 1 {print $2, $3}' sales.csv
keyboard 2
mouse 5
monitor 1
keyboard 1
cable 10
mouse 2
monitor 2

Ook de uitvoer van andere commando's kun je via een pipe doorgeven en zo splitsen. Toen we bestandsgrootte ($5) en naam ($9) uit de uitvoer van ls -l kozen, was de eerste regel leeg, omdat de eerste regel van ls -l, [total 24], geen vijfde en negende veld heeft.

ls -l | awk '{print $5, $9}'

1567 access.log
79 quoted.csv
207 sales.csv
85 scores-copy.txt
85 scores.txt
315 users.txt

Met NR > 1 valt de eerste regel weg en blijven alleen bestandsgroottes en namen over.

ls -l | awk 'NR > 1 {print $5, $9}'
1567 access.log
79 quoted.csv
207 sales.csv
85 scores-copy.txt
85 scores.txt
315 users.txt

4️⃣ awk BEGIN, END, sommen en gemiddelden

  • ↪️ Variabelen en printf-uitvoerformaten

Een BEGIN-blok draait één keer voordat de eerste regel wordt gelezen, een END-blok één keer nadat de laatste regel is verwerkt. Voor een som tel je op elke regel op bij een variabele en toon je die in END. Het onderstaande schema toont de volgorde die awk per regel doorloopt bij het optellen van de bedragen in de verkoopgegevens.

🔁 Volgorde waarin awk sales.csv regel voor regel verwerkt
Uitlegdiagram
🔁 Verwerkingsvolgorde
$ awk -F, 'NR > 1 {t += $3 * $4} END {printf "total %.2f\n", t}' sales.csv
① Gelezen regelNR = 1date,item,qty,priceNR = 22026-10-01,keyboard,2,45.00NR = 32026-10-01,mouse,5,19.90NR = 82026-10-04,monitor,2,189.00Geen regels meer om te lezenRegel 8 is de laatste regel.
② Velden splitsen (-F,)$1date$2item$3qty$4priceDe kopregel wordt op dezelfde manier gesplitst.$12026-10-01$2keyboard$32$445.00$3 aantal, $4 stukprijs$12026-10-01$2mouse$35$419.90$3 aantal, $4 stukprijs$12026-10-04$2monitor$32$4189.00$3 aantal, $4 stukprijsGeen regel om te splitsenHet END-blok leest geen regels.
③ Patroon en actieNR > 1 onwaarDe actie wordt overgeslagen.t = (leeg)NR > 1 waart += 2 * 45.00t = 90NR > 1 waart += 5 * 19.90t = 189.5NR > 1 waart += 2 * 189.00t = 886.3END wordt uitgevoerdtotal 886.30printf toont t met twee decimalen.
De eerste regel is de kopregel, dus NR > 1 is onwaar en awk gaat zonder actie naar de volgende regel.
Vanaf de tweede regel is het patroon waar, en 90, het aantal maal de stukprijs, wordt bij de variabele t opgeteld.
De variabele t behoudt zijn waarde van regel tot regel, dus de som tot en met de derde regel is 189.5.
Regels 4 tot en met 7 volgen dezelfde volgorde, en tot en met de laatste regel 8 komt t uit op 886.3.
Nadat de laatste regel is verwerkt, draait het END-blok één keer en toont printf total 886.30.

De som van alle verzonden bytes ($10) in het toegangslog was 41298 bytes. Een variabele die voor het eerst wordt gebruikt, begint leeg (als getal 0), dus je hoeft hem niet op 0 te zetten.

awk '{sum += $10} END {print sum}' access.log
41298

Toon je de som niet in END maar in de actie die op elke regel draait, dan zie je bij elke regel het tussentotaal. Toon je bij elke optelling het regelnummer en t, dan krijg je zeven regels zonder de kop, en de 886.3 op de laatste regel is het eindtotaal.

awk -F, 'NR > 1 {t += $3 * $4; print NR, t}' sales.csv
2 90
3 189.5
4 378.5
5 423.5
6 468.5
7 508.3
8 886.3

Het gemiddelde bereken je in END door de som te delen door het aantal regels. De som van de vijf scores was 343, het gemiddelde 68.6.

awk '{total += $3; n++} END {print total, n, total / n}' scores.txt
343 5 68.6

Met BEGIN toon je één keer een kopregel boven de resultaten. Boven de artikelen en bedragen (aantal × stukprijs) verschijnt de regel item total maar één keer.

awk -F, 'BEGIN {print "item", "total"} NR > 1 {print $2, $3 * $4}' sales.csv
item total
keyboard 90
mouse 99.5
monitor 189
keyboard 45
cable 45
mouse 39.8
monitor 378

Het uitvoerscheidingsteken verander je in BEGIN met de variabele OFS. Zet je OFS op een komma, dan komt op de plek van de komma's in print een komma in plaats van een spatie, en verschijnt de accountlijst in CSV-vorm.

awk 'BEGIN {FS = ":"; OFS = ","} {print $1, $3, $7}' users.txt
root,0,/bin/bash
bin,1,/sbin/nologin
daemon,2,/sbin/nologin
nobody,65534,/sbin/nologin
user,1000,/bin/bash
deploy,1001,/bin/bash
backup,1002,/sbin/nologin

Om kolommen uit te lijnen gebruik je printf. %-10s is een links uitgelijnde tekenreeks van 10 posities, %3d een geheel getal van 3 posities en %8.2f een getal van 8 posities met twee decimalen.

awk -F, 'NR > 1 {printf "%-10s %8.2f\n", $2, $3, $3 * $4}' sales.csv
keyboard     2    90.00
mouse        5    99.50
monitor      1   189.00
keyboard     1    45.00
cable       10    45.00
mouse        2    39.80
monitor      2   378.00

Anders dan print gaat printf niet naar een nieuwe regel, dus zet [\n] aan het einde van het formaat. Zonder [\n] lopen de artikelnamen op één regel door.

awk -F, 'NR > 1 {printf "%s ", $2}' sales.csv
keyboard mouse monitor keyboard cable mouse monitor

5️⃣ Loganalyse en opties van het awk-commando

  • ↪️ Client-IP's en statuscodes tellen, opties op een rij

🔲 Loganalyse

Optellen bij één variabele geeft maar één totaal. Om per client-IP of statuscode te tellen, verzamel je de waarden in een array. n[$1]++ telt 1 op bij het arrayvak met het IP als sleutel, en for (ip in n) in END haalt de verzamelde vakken één voor één op.

awk '{n[$1]++} END {for (ip in n) print n[ip], ip}' access.log | sort -rn
4 192.0.2.10
3 203.0.113.25
3 198.51.100.7
2 192.0.2.44

De volgorde waarin for (ip in n) ze ophaalt ligt niet vast (volgens de GNU Awk-handleiding), dus hebben we met sort -rn op aantal verzoeken gesorteerd. 192.0.2.10 had er met 4 het meest.

Het aantal per statuscode tel je op dezelfde manier. 404 kwam 3 keer voor, 500 één keer.

awk '{n[$9]++} END {for (s in n) print s, n[s]}' access.log | sort
200 6
301 1
304 1
404 3
500 1

Haal je alleen de statuscodes eruit en geef je ze door aan sort en uniq -c, dan krijg je dezelfde aantallen.

awk '{print $9}' access.log | sort | uniq -c
      6 200
      1 301
      1 304
      3 404
      1 500

Om alleen foutantwoorden te zien, zet je een voorwaarde op de statuscode. De regels vanaf 400 waren drie verzoeken naar wp-login.php en .env en één 500-fout.

awk '$9 >= 400 {print $9, $1, $7}' access.log
404 203.0.113.25 /wp-login.php
404 203.0.113.25 /wp-login.php
404 203.0.113.25 /.env
500 198.51.100.7 /api/search?q=awk

Ook de verzonden bytes per IP tel je op in een array. 192.0.2.10 ontving met 31340 bytes het meest.

awk '{b[$1] += $10} END {for (ip in b) print b[ip], ip}' access.log | sort -rn
31340 192.0.2.10
5120 192.0.2.44
4250 198.51.100.7
588 203.0.113.25

Het tijdveld ($4) kun je als tekenreeks vergelijken. Bij regels met dezelfde datum en hetzelfde formaat komt de tekenvolgorde overeen met de tijdvolgorde, dus hebben we alleen de vier verzoeken van 00:05 tot net voor 00:10 geselecteerd.

awk '$4 >= "[29/Oct/2026:00:05" && $4 < "[29/Oct/2026:00:10" {print $4, $7}' access.log
[29/Oct/2026:00:05:30 /contact.html
[29/Oct/2026:00:07:02 /old-page.html
[29/Oct/2026:00:07:15 /.env
[29/Oct/2026:00:09:48 /index.html

🔲 Opties van het awk-commando

📌 Belangrijkste opties: resultaten uit dit artikel

OptieTaakResultaat in dit artikel
-F fsStelt het scheidingsteken voor invoervelden in-F: scheidt accountnaam ($1) en loginshell ($7) in users.txt, -F, toont artikel en aantal uit sales.csv samen met de kop (item qty)
-v var=valGeeft een variabele een waarde voordat het programma startDe shellvariabele min doorgeven met -v min=$min toont zes regels met minstens 1000 verzonden bytes, met -v FPAT=… wordt een kolom tussen aanhalingstekens in quoted.csv één veld
-i inplaceSlaat de uitvoer op in het oorspronkelijke bestand in plaats van op het schermNa gawk -i inplace verschijnt niets op het scherm en heeft de kopie van scores.txt nog twee kolommen, naam en score, met -v inplace::suffix=.bak blijft de vorige inhoud in een .bak-bestand staan
--versionToont versie-informatieDe eerste regel van [awk --version] toont versie GNU Awk 5

📎 Andere opties: volgens de officiële handleiding

OptieTaak
-f program-fileLeest het AWK-programma uit een bestand in plaats van het eerste opdrachtregelargument, -f kan meerdere keren worden opgegeven
-e program-textGebruikt de tekst op de opdrachtregel als AWK-programmabron, te combineren met bibliotheekfuncties uit -f of --include
-E fileLijkt op -f, maar wordt als laatste verwerkt en blokkeert variabeletoewijzingen op de opdrachtregel, voor #!-scripts
--traditionalDraait in compatibiliteitsmodus en herkent geen GNU-uitbreidingen
--posixZet compatibiliteitsmodus aan met extra beperkingen, herkent bijvoorbeeld func, het synoniem van function, niet
--lintWaarschuwt voor twijfelachtige of moeilijk naar andere AWK-implementaties over te zetten constructies, met --lint=fatal worden waarschuwingen fatale fouten
--dump-variablesSchrijft een gesorteerde lijst van globale variabelen met type en eindwaarde naar een bestand, zonder bestandsnaam naar awkvars.out

🔲 Simulator voor het awk-commando

In de simulator hieronder kun je zelf awk-commando's invoeren op dezelfde testbestanden.

Simulator voor het awk-commandoGNU Awk 5
[root@server work]#
Een kleine awk-interpreter die alleen in je browser werkt. De vier testbestanden zijn dezelfde als bij de metingen, en met ↑↓ haal je eerdere commando's terug.

🔢 FAQ & aanbevolen content

$min tussen enkele aanhalingstekens wordt niet door de shell vervangen en komt ongewijzigd bij awk aan, dus geef het door met de optie -v. Zet je 1000 in de shellvariabele min en geef je -v min=$min door, dan verschijnen de zes regels met minstens 1000 verzonden bytes. Zet je het awk-programma tussen dubbele aanhalingstekens, dan vervangt de shell eerst zelfs de $1 in [print $1] door een lege waarde, en wordt de hele regel getoond.

Met -i inplace slaat GNU Awk de uitvoer op in het oorspronkelijke bestand in plaats van op het scherm. Toen we een programma dat het eerste en derde veld toont met gawk -i inplace op een kopie van scores.txt uitvoerden, verscheen er niets op het scherm en had het bestand nog twee kolommen, naam en score. Omdat het oorspronkelijke bestand direct wordt overschreven, blijft met -v inplace::suffix=.bak de vorige inhoud in een .bak-bestand staan.

Op de AlmaLinux 9-server was /usr/bin/awk een symbolische koppeling naar gawk, en de eerste regel van [awk --version] toonde versie GNU Awk 5. Op deze server voeren de twee namen hetzelfde programma uit. Controleer voordat je GNU Awk-functies zoals -i inplace of FPAT gebruikt met [awk --version] of het GNU Awk is.

ℹ️ Affiliatemelding
De content van deze site bevat affiliatelinks. Koopt een bezoeker via een van deze links een product of dienst, dan ontvangt deze site een commissie van de verkoper. Het bedrag dat de koper betaalt (bij acties gaat het omlaag ↓) wordt daardoor niet hoger. De vermelde prijzen, kortingen en voorraad gelden op het moment van schrijven en kunnen afwijken; controleer ze daarom vóór je aankoop bij de verkoper. Producten worden gekozen en beoordeeld volgens onze eigen criteria, en commissies hebben geen invloed op de volgorde of de inhoud van de beoordelingen.

Geef een reactie

Je e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *

Laat zien dat je geen machine bent: 9   +   1   =