Tips en Trucs 2019

Reguliere expressies

Bij het behandelen van bestanden, mappen en de inhoud van bestanden kan je niet omheen reguliere expressies (regular expression, regexp of regex). Reguliere expressies zijn tekens die een patroon vormen. Reguliere expressie patronen worden gebruikt om teksten en lijsten met mappen en bestanden te doorzoeken.

Zoeken

De meerderheid van de zoekacties worden uitgevoerd door de grep opdracht. De grep opdracht zoekt met behulp van reguliere expressies naar patronen in een bestand of tekststroom (text stream).

Om met reguliere expressies en grep te leren werken, maken we het tekstbestand grephelp.txt aan met de opdracht:

dany@main:~> grep --help > grephelp.txt

Het bestand grephelp.txt bevat nu de help informatie die je krijgt bij het uitvoeren van de opdracht grep --help.

Om in het bestand greptext.txt te zoeken naar de lettercombinatie 'ine' gebruiken we de opdracht:

dany@pindabook:~> grep 'ine' grephelp.txt 
  -i, --ignore-case         verschil tussen hoofd- en kleine letters negeren
  -x, --line-regexp         patronen komen alleen overeen met een hele regel
  -n, --line-number         bij de uitvoerregels het regelnummer tonen
      --line-buffered       elke uitvoerregel direct tonen

Ben je enkel geïnteresseerd in het aantal keer dat het tekstfragment 'ine' in het bestand grephelp.txt voorkomt, laat grep dan tellen (count):

dany@pindabook:~> grep -c 'ine' grephelp.txt 
4

Ben je op zoek naar een tekstfragment dat begint met 'in' gevolgd door nog een teken:

dany@pindabook:~> grep 'in.' grephelp.txt
Zoekt naar PATROON in ieder gegeven BESTAND.
    Voorbeeld:  grep -i 'hallo wereld' menu.h main.c
Keuze en interpretatie van het patroon:
  -F, --fixed-strings       PATROON is een serie tekenreeksen,
  -i, --ignore-case         verschil tussen hoofd- en kleine letters negeren
  -x, --line-regexp         patronen komen alleen overeen met een hele regel
  -z, --null-data           regels eindigen op 0-byte, niet op LF-teken
  -s, --no-messages         foutmeldingen onderdrukken
  -v, --invert-match        de niet-overeenkomende regels selecteren
  -n, --line-number         bij de uitvoerregels het regelnummer tonen
      --line-buffered       elke uitvoerregel direct tonen
      --label=LABEL         dit LABEL als naam voor standaardinvoer gebruiken
  -o, --only-matching       alleen het overeenkomende regelfragment tonen
      --binary-files=TYPE   aannemen dat binaire bestanden van dit TYPE zijn;
                              TYPE is 'binary' (binair), 'text' (als tekst),
  -a, --text                hetzelfde als '--binary-files=text'
  -I                        hetzelfde als '--binary-files=without-match'
                              (ofwel lezen, in-afdalen, of overslaan)
  -r, --recursive           afdalen in submappen (ofwel '--directories=recurse')
  -R, --dereference-recursive   idem, maar alle symbolische koppelingen volgen
      --include=BESTANDSPATROON  alleen bestanden doorzoeken die aan
  -T, --initial-tab         tabs uitlijnen (eventueel een tab-teken invoegen)
  -Z, --null                een 0-byte invoegen na iedere bestandsnaam
Contextbesturing:
  -U, --binary              geen CR-tekens weghalen bij regeleinde (MSDOS/Windows)
Indien BESTAND '-' is, wordt standaardinvoer gelezen.  Zonder een BESTAND
wordt '.' gelezen indien in recursieve modus, anders wordt '-' gelezen.
Bij minder dan twee BESTANDen wordt '-h' aangenomen.
De afsluitwaarde is 0 in geval van overeenkomsten, anders 1; als er
Rapporteer gebreken in het programma aan <bug-grep@gnu.org>;
meld fouten in de vertaling aan <vertaling@vrijschrift.org>.
Webpagina van GNU grep: <http://www.gnu.org/software/grep/>

Gebruik meerdere punten als je op zoek gaat naar 'in' gevolgd door meerdere tekens:

dany@pindabook:~> grep 'in..' grephelp.txt
Zoekt naar PATROON in ieder gegeven BESTAND.
    Voorbeeld:  grep -i 'hallo wereld' menu.h main.c
Keuze en interpretatie van het patroon:
  -F, --fixed-strings       PATROON is een serie tekenreeksen,
  -i, --ignore-case         verschil tussen hoofd- en kleine letters negeren
  -x, --line-regexp         patronen komen alleen overeen met een hele regel
  -z, --null-data           regels eindigen op 0-byte, niet op LF-teken
  -s, --no-messages         foutmeldingen onderdrukken
  -v, --invert-match        de niet-overeenkomende regels selecteren
  -n, --line-number         bij de uitvoerregels het regelnummer tonen
      --line-buffered       elke uitvoerregel direct tonen
      --label=LABEL         dit LABEL als naam voor standaardinvoer gebruiken
  -o, --only-matching       alleen het overeenkomende regelfragment tonen
      --binary-files=TYPE   aannemen dat binaire bestanden van dit TYPE zijn;
                              TYPE is 'binary' (binair), 'text' (als tekst),
  -a, --text                hetzelfde als '--binary-files=text'
  -I                        hetzelfde als '--binary-files=without-match'
                              (ofwel lezen, in-afdalen, of overslaan)
  -r, --recursive           afdalen in submappen (ofwel '--directories=recurse')
  -R, --dereference-recursive   idem, maar alle symbolische koppelingen volgen
      --include=BESTANDSPATROON  alleen bestanden doorzoeken die aan
  -T, --initial-tab         tabs uitlijnen (eventueel een tab-teken invoegen)
  -Z, --null                een 0-byte invoegen na iedere bestandsnaam
Contextbesturing:
  -U, --binary              geen CR-tekens weghalen bij regeleinde (MSDOS/Windows)
Indien BESTAND '-' is, wordt standaardinvoer gelezen.  Zonder een BESTAND
wordt '.' gelezen indien in recursieve modus, anders wordt '-' gelezen.
Bij minder dan twee BESTANDen wordt '-h' aangenomen.
De afsluitwaarde is 0 in geval van overeenkomsten, anders 1; als er
Rapporteer gebreken in het programma aan <bug-grep@gnu.org>;
meld fouten in de vertaling aan <vertaling@vrijschrift.org>.
Webpagina van GNU grep: <http://www.gnu.org/software/grep/>

De reguliere expressie 'ing*' vindt zowel 'in', 'ing', 'ingg', met andere woorden het tekstfragment 'in' gevolgd door geen enkele of een aantal g-tekens:

dany@pindabook:~> grep 'ing*' grephelp.txt
Zoekt naar PATROON in ieder gegeven BESTAND.
    Voorbeeld:  grep -i 'hallo wereld' menu.h main.c
Keuze en interpretatie van het patroon:
  -F, --fixed-strings       PATROON is een serie tekenreeksen,
  -i, --ignore-case         verschil tussen hoofd- en kleine letters negeren
  -x, --line-regexp         patronen komen alleen overeen met een hele regel
  -z, --null-data           regels eindigen op 0-byte, niet op LF-teken
  -s, --no-messages         foutmeldingen onderdrukken
  -v, --invert-match        de niet-overeenkomende regels selecteren
  -n, --line-number         bij de uitvoerregels het regelnummer tonen
      --line-buffered       elke uitvoerregel direct tonen
      --label=LABEL         dit LABEL als naam voor standaardinvoer gebruiken
  -o, --only-matching       alleen het overeenkomende regelfragment tonen
      --binary-files=TYPE   aannemen dat binaire bestanden van dit TYPE zijn;
                              TYPE is 'binary' (binair), 'text' (als tekst),
  -a, --text                hetzelfde als '--binary-files=text'
  -I                        hetzelfde als '--binary-files=without-match'
                              (ofwel lezen, in-afdalen, of overslaan)
  -r, --recursive           afdalen in submappen (ofwel '--directories=recurse')
  -R, --dereference-recursive   idem, maar alle symbolische koppelingen volgen
      --include=BESTANDSPATROON  alleen bestanden doorzoeken die aan
      --exclude-from=BESTAND     bestanden overslaan die aan een patroon in
  -T, --initial-tab         tabs uitlijnen (eventueel een tab-teken invoegen)
  -Z, --null                een 0-byte invoegen na iedere bestandsnaam
Contextbesturing:
  -U, --binary              geen CR-tekens weghalen bij regeleinde (MSDOS/Windows)
Indien BESTAND '-' is, wordt standaardinvoer gelezen.  Zonder een BESTAND
wordt '.' gelezen indien in recursieve modus, anders wordt '-' gelezen.
Bij minder dan twee BESTANDen wordt '-h' aangenomen.
De afsluitwaarde is 0 in geval van overeenkomsten, anders 1; als er
Rapporteer gebreken in het programma aan <bug-grep@gnu.org>;
meld fouten in de vertaling aan <vertaling@vrijschrift.org>.
Webpagina van GNU grep: <http://www.gnu.org/software/grep/>

Zoek je naar meerdere tekstfragmenten tegelijk, bijvoorbeeld naar 'before' en 'after':

dany@pindabook:~> grep '\(before\|after\)' grephelp.txt
  -B, --before-context=AANTAL   dit AANTAL regels voorafgaande context tonen
  -A, --after-context=AANTAL    dit AANTAL regels nakomende context tonen

Let in de reguliere expressie op de tekens voorafgegaan door \, namelijk '(', '|' en ')'. Het escape-teken \ is het teken dat ervoor zorgt dat de reguliere expressie haken en of ziet, in plaats van de leestekens '(', '|' en ')'. De haken groeperen patronen, het |-teken stelt of voor. Deze reguliere expressie zoekt dus naar de woorden 'before' of 'after'.

Zoek je naar de woorden met een gemeenschappelijk deel, zoals 'matching' en 'matches', wordt de opdracht:

dany@pindabook:~> grep 'match\(ing\|es\)' grephelp.txt
  -o, --only-matching       alleen het overeenkomende regelfragment tonen
  -l, --files-with-matches  alleen namen van bestanden met overeenkomsten tonen

Ankers

Een anker (anchor) bepaald een positie. Het anker '^' bepaald het begin van een regel, het '$' anker het einde van een regel.

Met een ls -l opdracht kan je de inhoud van een map weergeven. Daarbij stelt de eerste letter het type bestand voor, zo hebben alle mappen als eerste letter de 'd' van directory. Om alle mappen uit een ls -l opdracht te filteren, geven we de uitvoer door aan een grep opdracht:

dany@pindabook:~> ls -l | grep '^d'
drwxr-xr-x 4 dany users   4096 28 jan 14:30 Besturingssystemen
drwxr-xr-x 2 dany users   4096 27 mei  2018 bin
drwxr-xr-x 2 dany users   4096 27 mei  2018 Bureaublad
drwxr-xr-x 3 dany users   4096 28 jan 16:28 Downloads
drwxr-xr-x 3 dany users   4096  4 jan 18:38 Nextcloud
drwxr-xr-x 4 dany users   4096 28 mei  2018 onedrive
drwxr-xr-x 3 dany users   4096 28 mei  2018 OneDrive

Op dezelfde manier zoek je in het bestand grephelp.txt naar regels die eindigen met een 'l':

dany@pindabook:~> grep 'l$' grephelp.txt
                              elke tekenreeks op een aparte regel
  -x, --line-regexp         patronen komen alleen overeen met een hele regel

Of alle regels die eindigen op 'el':

dany@pindabook:~> grep 'el$' grephelp.txt
                              elke tekenreeks op een aparte regel
  -x, --line-regexp         patronen komen alleen overeen met een hele regel

Complexere zoekopdrachten kan je uitvoeren door zoekopdrachten te combineren. Zo zoek je alle regels op die beginnen met 'D' en geef je het resultaat door aan een grep opdracht die in het resultaat zoekt naar de regels die eindigen op een dubbele punt:

dany@pindabook:~> grep '^D' grephelp.txt --color=always | grep ':$'
Diversen:

De --color=always optie zorgt dat de eerste 'D' de rode gevonden kleur blijft behouden. Let echter op, zo'n opties kunnen uw zoekopdrachten ernstig storen.

regex