De UNIX grep opdracht zoekt naar tekstfragmenten in bestanden. De find opdracht daarentegen zoekt naar bestanden met een bepaalde naam of eigenschappen. Vandaag publiceer ik wat tips om met grep sneller en efficiënter bestanden te doorzoeken.
Eerst een paar opmerkingen over grep:
Zoals met veel UNIX opdrachten, kan wegens de voorgeschiedenis en compatibiliteit met vorige versies, grep deze extra mogelijkheden maar gebruiken door het opgeven van extra opties.
GNU grep (standaard aanwezig in de meeste Linux distributies) ondersteunt veel opties, zoals kleuren. BSD grep (aanwezig in op BSD gebaseerde besturingssystemen zoals OSX) ondersteunt minder opties. De systemen zonder GNU grep kunnen steeds GNU grep installeren, GNU grep is namelijk voor alle systemen beschikbaar.
Het volgende voorbeeld doorzoekt hoofdletter ongevoelig (i), recursief (-R) in de opgegeven map en onderliggende mappen naar de tekst <title> in (--include) HTML bestanden:
grep -Ri --include="*.html" '<title>' ~/Documents/SNT/Linux/Web
Grep kan in de uitvoer zaken zoals bestandsnamen, regelnummers, gezochte tekst en omringende tekst accentueren met kleuren. Deze opties kan je best opslaan in omgevingsvariabelen:
GREP_OPTIONS="--color=always" GREP_COLORS="ms=01;37:mc=01;37:sl=:cx=01;30:fn=35:ln=32:bn=32:se=36"
En testen door deze voor een grep opdracht te plaatsen:
GREP_OPTIONS="--color=always" GREP_COLORS="ms=01;37:mc=01;37:sl=:cx=01;30:fn=35:ln=32:bn=32:se=36" grep -Ri --include="*.html" '<title>' ~/Documents/SNT/Linux/Web
Opmerking: gebruik GREP_COLORS, en niet de afgeschreven omgevingsvariabele GREP_COLOR. De eerste omgevingsvariabele heeft ook veel meer mogelijkheden.
Standaard decodeert grep de tekstbestanden. Dit vraagt tijd. Als je platte ASCII teksten, zoals broncode van programmeertalen doorzoekt, kun je veel tijd sparen door het decoderen uit te schakelen. Dit doe je door de omgevingsvariabele LC_CTYPE tijdelijk aan te passen naar POSIX.
LC_CTYPE=POSIX grep ...
Met de opties --before-context en --after-context kan je de regels voor en na de zoektekst weergeven. Bij broncode zorgt de optie --line-number voor het nummeren van de weergegeven regels.
# Search ASCII-string from multiple files in the currect working directory
# E.g.
# search "foobar" "*.html"
# search "foobar" "*.html" myfolder
# By default we excluse dotted files and directoves (.git, .svn)
if [[ ! -n "$1" ]] ; then
echo "Usage: search \"pattern\" \"*.filemask\" \"path\""
return
fi
# Did we get path arg
if [[ ! -n "$3" ]] ;
then
search_path="."
else
search_path="$3"
fi
# LC_CTYPE="posix" 20x increases performance for ASCII search
# https://twitter.com/jlaurila/status/86750682094374912
# We use specially tuned GREP colors - make sure you have GNU grep on OSX
# https://github.com/miohtama/ztanesh/blob/master/README.rst
GREP_COLORS="ms=01;37:mc=01;37:sl=:cx=01;30:fn=35:ln=32:bn=32:se=36" LC_CTYPE=POSIX \
grep -Ri "$1" --line-number --before-context=3 --after-context=3 --color=always --include="$2" --exclude=".*" "$search_path"/*