Les 3
Tekst bekijken, zoeken en combineren
Zoeken in bestanden met grep, uitvoer omleiden met > en >> en commando's aan elkaar koppelen met pipes.
🎯 Na deze les kun je
- zoeken met grep
- uitvoer omleiden
- commando's koppelen met pipes
Als je een server beheert, kijk je de hele dag naar tekst: logbestanden, configuratie, uitvoer van commando's. Een webserver-log kan honderdduizenden regels hebben. Die lees je niet van boven naar beneden; je zoekt erin, filtert wat je nodig hebt, en telt. In deze les leer je bestanden bekijken, zoeken met grep, uitvoer omleiden naar bestanden, en kleine commando's aan elkaar koppelen tot een krachtige analyse.
Bestanden bekijken
| Commando | Doet |
|---|---|
cat bestand |
hele bestand tonen (handig voor korte bestanden) |
less bestand |
bladeren: pijltjes, spatie, /woord zoeken, q stoppen |
head bestand |
de eerste 10 regels (head -n 3 voor 3) |
tail bestand |
de laatste 10 regels |
tail -f bestand |
het eind blijven volgen terwijl er regels bijkomen; stop met Ctrl+C |
wc -l bestand |
het aantal regels tellen (word count, -l = lines) |
tail -f gebruik je constant bij het beheren van servers: je ziet nieuwe logregels binnenkomen terwijl je in een browser de site probeert.
In deze les gebruiken we dit voorbeeld-log van een webserver, access.log:
203.0.113.5 - - [12/Oct/2026:10:01:12 +0200] "GET / HTTP/1.1" 200 5120
198.51.100.23 - - [12/Oct/2026:10:01:15 +0200] "GET /cursussen HTTP/1.1" 200 8890
203.0.113.5 - - [12/Oct/2026:10:01:20 +0200] "GET /login HTTP/1.1" 200 2048
192.0.2.77 - - [12/Oct/2026:10:02:03 +0200] "GET /wp-login.php HTTP/1.1" 404 512
192.0.2.77 - - [12/Oct/2026:10:02:04 +0200] "GET /admin HTTP/1.1" 404 512
192.0.2.77 - - [12/Oct/2026:10:02:05 +0200] "GET /.env HTTP/1.1" 404 512
198.51.100.23 - - [12/Oct/2026:10:03:41 +0200] "POST /login HTTP/1.1" 302 0
192.0.2.77 - - [12/Oct/2026:10:04:10 +0200] "GET /phpmyadmin HTTP/1.1" 404 512
203.0.113.5 - - [12/Oct/2026:10:05:00 +0200] "GET /cursussen/python HTTP/1.1" 200 7340
Elke regel is één verzoek: het IP-adres van de bezoeker, het tijdstip, het verzoek (methode en pad), de statuscode (les 32 van de hoofdcursus: 200 = OK, 404 = niet gevonden) en het aantal bytes.
Zoeken met grep
grep patroon bestand toont alle regels waarin het patroon voorkomt:
$ grep -i "login" access.log
203.0.113.5 - - [12/Oct/2026:10:01:20 +0200] "GET /login HTTP/1.1" 200 2048
192.0.2.77 - - [12/Oct/2026:10:02:03 +0200] "GET /wp-login.php HTTP/1.1" 404 512
198.51.100.23 - - [12/Oct/2026:10:03:41 +0200] "POST /login HTTP/1.1" 302 0
De belangrijkste opties:
| Optie | Betekent | Voorbeeld |
|---|---|---|
-i |
hoofdletters negeren | grep -i error |
-n |
regelnummers erbij | grep -n POST access.log |
-c |
alleen het aantal tonen | grep -c " 404 " access.log → 4 |
-v |
regels zonder het patroon | grep -v " 200 " |
-r |
recursief in alle bestanden van een map | grep -r "Listen" /etc/apache2 |
-w |
alleen hele woorden | grep -w "fout" vindt niet foutje |
Zet het patroon tussen aanhalingstekens als er spaties of speciale tekens in staan. " 404 " met spaties eromheen voorkomt dat je ook een regel met 512404 bytes vindt.
Uitvoer omleiden
Normaal gaat de uitvoer van een commando naar het scherm. Met redirects stuur je hem ergens anders heen:
| Teken | Doet | Voorbeeld |
|---|---|---|
> |
uitvoer naar een bestand (overschrijft!) | grep " 404 " access.log > fouten.txt |
>> |
uitvoer achteraan een bestand toevoegen | date >> log.txt |
2> |
foutmeldingen naar een bestand | ls /bestaatniet 2> fouten.txt |
2>&1 |
foutmeldingen naar dezelfde plek als de uitvoer | commando > alles.txt 2>&1 |
< bestand |
invoer uit een bestand | wc -l < access.log |
Een programma heeft twee uitvoerkanalen: standaarduitvoer (stdout), nummer 1, voor gewone uitvoer, en standaardfout (stderr), nummer 2, voor foutmeldingen. Daarom zie je een foutmelding nog op het scherm als je alleen > gebruikt.
/dev/null is een speciaal bestand dat alles weggooit wat je erin schrijft. commando 2> /dev/null laat foutmeldingen verdwijnen. Handig, maar gebruik het bewust: soms is die foutmelding precies wat je moet weten.
> maakt het doelbestand eerst leeg, nog voordat het commando start. sort data.txt > data.txt laat je dus achter met een leeg bestand. Schrijf naar een nieuw bestand en hernoem daarna.
Pipes: commando's koppelen
Met de pipe | wordt de uitvoer van het ene commando de invoer van het volgende. Zo bouw je met kleine gereedschappen een grote analyse. Een paar gereedschappen die je vaak in een pipe ziet:
| Commando | Doet |
|---|---|
wc -l |
regels tellen |
sort |
sorteren (-n numeriek, -r omgekeerd) |
uniq |
opeenvolgende dubbele regels samenvoegen; -c telt ze |
head -n 5 |
de eerste 5 regels |
cut -d' ' -f1 |
kolom 1 uitknippen, met spatie als scheidingsteken |
$ grep " 404 " access.log | wc -l
4
"Zoek de regels met 404, en tel ze." Lees een pipe van links naar rechts.
Een logbestand analyseren
Welk IP-adres doet de meeste verzoeken? Bouw de pipe stap voor stap op en kijk na elke stap naar de uitvoer:
$ cut -d' ' -f1 access.log
203.0.113.5
198.51.100.23
203.0.113.5
192.0.2.77
...
Stap 1: alleen het IP-adres (het eerste veld). Nu sorteren, zodat gelijke adressen onder elkaar staan, en tellen met uniq -c:
$ cut -d' ' -f1 access.log | sort | uniq -c
4 192.0.2.77
2 198.51.100.23
3 203.0.113.5
uniq voegt alleen opeenvolgende gelijke regels samen; daarom moet sort ervoor. Tot slot sorteren op het aantal, hoogste eerst, en alleen de top tonen:
$ cut -d' ' -f1 access.log | sort | uniq -c | sort -rn | head -n 1
4 192.0.2.77
Kijk nu met grep wat dat adres deed:
$ grep "192.0.2.77" access.log
192.0.2.77 - - [12/Oct/2026:10:02:03 +0200] "GET /wp-login.php HTTP/1.1" 404 512
192.0.2.77 - - [12/Oct/2026:10:02:04 +0200] "GET /admin HTTP/1.1" 404 512
192.0.2.77 - - [12/Oct/2026:10:02:05 +0200] "GET /.env HTTP/1.1" 404 512
192.0.2.77 - - [12/Oct/2026:10:04:10 +0200] "GET /phpmyadmin HTTP/1.1" 404 512
Vier verzoeken binnen twee minuten naar bekende beheerpagina's die op deze site niet bestaan. Dit is geen gewone bezoeker, maar een script dat zwakke plekken zoekt. Zulke scans zie je op elke server die aan het internet hangt. In les 19 leer je ze automatisch te blokkeren.
Bouw een pipe altijd stap voor stap op en bekijk de tussenuitvoer, eventueel met | head erachter. Dan zie je precies waar het misgaat als het eindresultaat niet klopt.
Oefenen
Oefening 1. Hoeveel verzoeken in access.log hadden niet status 200? Schrijf één pipe.
Modelantwoord oefening 1
$ grep -v " 200 " access.log | wc -l
5
Of korter: grep -vc " 200 " access.log.
Oefening 2. Maak een overzicht van hoe vaak elke statuscode voorkomt. Tip: de statuscode is het 9e veld als je op spaties splitst.
Modelantwoord oefening 2
$ cut -d' ' -f9 access.log | sort | uniq -c
4 200
1 302
4 404
Oefening 3. Je draait find / -name "*.conf" > configs.txt en het scherm loopt vol met Permission denied. Hoe bewaar je alleen de gevonden bestanden en gooi je de foutmeldingen weg?
Modelantwoord oefening 3
find / -name "*.conf" > configs.txt 2> /dev/null
> vangt stdout (de gevonden namen), 2> stuurt stderr (de foutmeldingen) naar /dev/null.
Lab: wie bestookt de webserver?
- Start het lab:
docker run -it --rm registry.wizg.it/webhosting/beetje-labs:les3. In~/logs/access.logstaat het log van een drukke dag (ruim 20.000 regels). - Tel het totale aantal verzoeken en het aantal 404-fouten.
- Zoek met één pipe het IP-adres met de meeste verzoeken. Schrijf het adres naar
~/antwoorden/top-ip.txt. - Zet alle regels van dat IP-adres in
~/antwoorden/verdacht.log. - Zet de vijf meest opgevraagde paden (het 7e veld), met aantallen, in
~/antwoorden/top-paden.txt. - Controleer met
beetje check les3.
Samenvatting
cat,less,head,tail(-fom te volgen) enwc -lom bestanden te bekijken en te tellen.grepzoekt regels;-i,-n,-c,-ven-rzijn de belangrijkste opties.>schrijft uitvoer naar een bestand (overschrijft),>>voegt toe,2>vangt foutmeldingen,/dev/nullgooit weg.- De pipe
|koppelt commando's;sort | uniq -c | sort -rn | headis het klassieke telpatroon. - Bouw pipes stap voor stap op en controleer de tussenuitvoer.
In les 4 ontdek je wie wat mag op een Linux-systeem: gebruikers, groepen en rechten.
Lab
In een webserver-log uitzoeken welk IP-adres de meeste requests doet
💻 Dit lab doe je op je eigen computer met Docker. Start de lab-container met (geeft de opdracht een eigen startcommando, gebruik dan dat):
$ docker run -it --rm registry.wizg.it/webhosting/beetje-labs:les3
Klaar? Controleer je werk met:
$ beetje check les3