blog_hero_Grep-tools

Grep-tools

Aug 11 2023

Wat is grep?

Volgens de man-pages is grep een programma dat naar patronen zoekt in bestanden. Er zijn zo verschillende soorten patronen die ondersteunt worden telkens een bepaalde vorm van reguliere expressies (regex). Regex verdient een eigen post dus daar in ga ik nog niet dieper in. Het soort patroon dat je wenst te gebruiken in grep, kan je bepalen met een flag;

  • G: Basis reguliere expressie. Dit is de standaard optie en moet je dus niet meegeven.
  • F: Fixed strings. Je gaat een opeenvolging van karakters meegeven en die moeten letterlijk teruggevonden worden. Hier kies je dus voor geen regex.
  • E: Extended: Dit is de meer complexere regex. Deze ga je willen gebruiken als je echt regex wilt gebruiken.
  • P: Perl compatible regular expressions (PCREs): Alsof reguliere expressies nog niet voldoende moeilijk was, bestaan er meerdere varianten. Deze vorm is afkomstig van de Perl programmeertaal.

Als je hulp nodig hebt met het opstellen van je regex query, kan je gebruik maken van regex 101 om eenvoudig je query te testen.

Enkele voorbeelden

# De meest basis zoekopdracht. Zoek TEKST in het bestand.
grep 'TEKST' <bestand>
# Toon alle lijnen behalve die met TEKST in het bestand
grep -v 'TEKST' <bestand>
# Zoek letterlijk naar onderstaande opeenvolging van karakters.
grep -F '.*\n' <bestand>
# Zoek in alle bestanden van onderliggende mappen naar TEKST.
grep -r 'TEKST' /pad/naar/map
# Zoek recursief naar meerdere patronen in een map. Dit is TEKST1 OF TEKST2.
grep -r -e 'TEKST1' -e 'TEKST2' /pad/naar/map
# Zoek in meerdere bestanden naar lijnen die eindigen met TEKST.
grep -E '^.TEKST$' -f <bestand1> -f <bestand2>

Andere grep-tools

Compressie

Vooral als we met log bestanden in een log rotatie werken, kan het zijn dat oudere logs gecomprimeerd worden om zo de bestandsgrootte te verkleinen. Toch kan het voorkomen dat we moeten zoeken in die bestanden naar problemen die zich nu voordoen en misschien al langen voorgedaan hebben. Je kan dan die bestanden terug uitpakken en dan grep gebruiken of je kan ook onderstaande tools gebruiken afhankelijk van de compressie en ineens zoeken in de gecomprimeerde bestanden.

  • bzgrep, bzfgrep, bzegrep: bzip2 compressie
  • zgrep: gzip compressie
  • zipgrep: zip compressie
  • xzgrep, xzegrep, xzfgrep, lzgrep, lzegrep, lzfgrep: compressie met xz, lzma, gzip, bzip2, lzop of zstd

Omdat dit een beetje complexer is doorlopen we hier even eenvolledig scenario. Ik kies om te werken met xzgrep omdat deze de meeste compressie standaarden ondersteunt. De kans is ook het grootste dat je deze nodig zal hebben.

# Eerst maken we een paar bestanden aan:
echo "appel" > bestand1
echo "1234567890" > bestand2
# Daarna stoppen we deze in een tarbal en vervolgens comprimeren we.
tar -cf bestanden.tar bestand1 bestand2
bzip2 -z bestanden.tar.bz2
# Nu kunnen we zoeken naar tekst in de gecomprimeerde map
xzgrep appel bestanden.tar.bz2
# Als de tekst gevonden wordt krijgen we onderstaande boodschap terug.
grep: (standard input): binary file matches
# Als het niet gevonden wordt, krijg je niets terug
xzgrep banaan bestanden.tar.bz2

Processen

Met pgrep kunnen we proces ID's zoeken. Deze tool hangt ook nauw samen met pkill en pidwait. Dit kan handig zijn om te zien welke processen bij een specifieke gebruiker horen. Daarnaast kan je ook zoeken of een bepaalde gebruiker een bepaald programma gebruikt, zoals bijvoorbeeld ssh. Op eerste zicht misschien niet zo handig om een lijst met PID's terug te krijgen. Dit commando wordt vooral interessant als je het combineert met andere commando's. Hieronder enkele voorbeelden.

# Stop alle tmux processen?
pkill $(pgrep tmux)
# Processen die je zelf uitvoert
pgrep -u $(whoami)
# Welke processen worden uitgevoerd vanaf /opt
pgrep -f '/opt'
# Chrome mag minder resources in gebruik nemen
renice +4 $(pgrep chrome)
# Controleer hoeveel resources Chrome in gebruik heeft
ps -ufp $(pgrep chrome)

Bonus: git grep

Niet echt een aparte tool maar wel leuk om weten dat git ook een optie grep bevat. Deze zal gelijkaardig werken als de originele grep en ondersteund ook grotendeels dezelfde flags. Let wel dat je hiervoor een git repository moet zitten om hiervan te genieten. Enkele voorbeelden:

# Zoek naar solution maar het mag niet in Documentatie zitten.
git grep solution -- :^Documentation
# Zoek naar bestanden met TEKST1 EN TEKST2
git grep --all-match -e TEKST1 -e TEKST2
# zoek naar TEKST in bestanden die untracked zijn
git grep --untracked TEKST
# Negeer git ignore en zoek in alle bestanden naar TEKST
git grep --no-exclude-standard TEKST