1.11. Buscar, ordenar i associar fitxers
1.11.2. «grep»
A la Wikipedia pots llegir que grep
és una utilitat de línia d’ordre per buscar conjunts de dades de text pla a la recerca de línies que coincideixin amb una expressió regular. El seu nom prové de l’ordre ed g/re/p
(globally search a regular expression and print, en català recerca global d’una expressió regular i imprimir), que té el mateix efecte.
L’ordre grep
té moltes i variades característiques, tant és així que hi ha llibres específics al respecte. L’ús més comú és filtrar línies d’entrada fent servir expressions regulars (en anglès, regexp).
Les opcions de l’ordre grep
comunament utilitzades es mostren a continuació. Els exemples es discutiran en seccions posteriors.
-i
ignora la distinció entre majúscules i minúscules en fer coincidències.-v
imprimeix només les línies que no coincideixen.-n
agrega un prefix de números de línia a les línies de sortida.-c
mostra només el recompte de línies de sortida.-l
imprimeix només els noms d’arxiu que coincideixen amb l’expressió donada.-L
imprimeix els noms d’arxiu que no coincideixen amb el patró.-w
fa coincidir el patró només amb paraules completes.-x
fa coincidir el patró només amb línies completes.-F
interpreta el patró com una cadena fixa (és a dir, no com una expressió regular).-o
imprimeix només les parts coincidents.-A N
imprimeix la línia coincident iN
línies després de la línia coincident.-B N
imprimeix la línia coincident iN
línies abans de la línia coincident-C N
imprimeix la línia coincident iN
línies abans i després de la línia coincident.-m N
imprimeix un màxim deN
línies coincidents.-q
sense sortida estàndard, surt immediatament si es troba una coincidència, útil en scripts.-s
suprimeix els missatges d’error, útil en scripts.-r
busca tots els arxius a les carpetes d’entrada especificades (per defecte els busca en el directori actual).-R
com-r
, però també segueix els enllaços simbòlics.--color=auto
ressalta les porcions coincidents, els noms d’arxiu, els números de línia, etc. usant colors.
Recerca literal
Els següents exemples també serien adequats amb l’opció -F
ja que no utilitzen expressions regulars. L’ordre grep
està prou ben dissenyada com per fer el que és correcte en aquests casos.
# Imprimeix línies que continguin l’string ’an’
. L’opció \n genera una nova línia
$ printf 'poma\nplatan\nmango\nfigura\ntango\n' | grep 'an'
platan mango tango
# Imprimeix coincidències sense distinció entre majúscules i minúscules
$ printf 'mussol\nsargantana\muSsoLina\ntres mussols\n' | grep -i 'mussol'
Mussol muSsoLina tres mussols
# Imprimeix coincidències de paraules completes
$ printf 'parell basic\nparitat\n3-parell' | grep -w 'parell'
parell basic 3-parell
# Imprimeix coincidències de línies buides i les compta
$ printf 'cel\n\nterra\n\n\n\ninfern\n' | grep -cx ''
4
# Imprimeix coincidències en una línia i les següents dues línies (A, after)
$ printf 'xarxa\ncactus\nsuculenta\npetunia\nesqueix' | grep -A2 'cactus'
cactus suculenta petunia
Expressions regulars
De forma predeterminada, grep tracta el patró de recerca com una expressió regular bàsica (en anglès, Basic Regular Expression: BRE).
-G
es pot utilitzar per especificar explícitament que es necessita BRE.-E
habilitarà expressions regulares esteses (en anglès, Extended Regular Expression: ERO). A GNU grep, BRE i ERO només difereixen en com s’especifiquen els metacaràcters; no hi ha diferència en les característiques.-F
farà que els patrons de recerca es tractin literalment.-P
habilitarà expressions regulares compatibles amb Perl, si està disponible (PCRE, per les seves sigles en anglès).
Les següents línies són les referències quan es volen utilitzar expressions regulars esteses. N’hi ha de diverses classes:
Àncores
- ^ restringeix la coincidència a l’inici de la cadena.
- $ restringeix la coincidència al final de la cadena.
- < restringeix la coincidència a l’inici de paraula.
- > restringeix la coincidència al final de paraula.
- \b restringeix la coincidència a l’inici/final de paraules.
- \B coincideix on \b no coincideix.
Metacaràcters i quantificadors
- . coincideix amb qualsevol caràcter, incloent-hi el caràcter de nova línia.
- ¿ coincideix 0 o 1 vegada.
- * coincideix 0 o més vegades.
- + coincideix 1 o més vegades.
- {m,n} coincideix de m a n
- {m,} coincideix almenys m
- {,n} coincideix fins a n (incloent-hi 0 vegades).
- {n} coincideix exactament n
Classes de caràcters
- [set123] coincideix amb qualsevol d’aquests caràcters una vegada.
- [^set123] coincideix, excepte amb qualsevol d’aquests caràcters, una vegada.
- [3-7AM-X] rang de caràcters des de 3 fins a 7, A, un altre rang des de M fins a X.
- \w similar a [a-zA-Z0-9_] per coincidir amb caràcters de paraules.
- \s similar a [ \t\n\r\f\v] per coincidir amb caràcters d’espai en blanc.
- \W coincideix amb caràcters que no són de paraules.
- \S coincideix amb caràcters que no són d’espai en blanc.
- [[:d igit:]] similar a [0-9] [[:alnum:]_] similar a \w
Es recomana veure el manual de l’ordre grep
per ser conscient de la versatilitat d’aquesta ordre.
Alternança i agrupació
- Pat1|pat2|pat3 coincideix amb pat1 o pat2 o pat3.
- () agrupa patrons, a(b|c)d és el mateix que abd|acd. També serveix com a grup de captura.
- \N referència cap enrere, proporciona la porció coincident de l’N-è grup de captura.
- \1 referència cap enrere al primer grup de captura.
- \2 referència cap enrere al segon grup de captura i així successivament fins a \9.
En el manual de grep
se citen les diferències entre BRE i ERE. En les expressions regulars bàsiques els metacaràcters ?, +, {, |, (i) perden el seu significat especial; en el seu lloc, s’utilitzen les versions amb barra invertida \?,\ +, \{,\ |, \( i \).
# Imprimeix la coincidència quan el final de la línia acaba amb –ar
$ printf 'pedalejar\ncorrer\nescriure\namar' | grep 'ar$'
pedalejar amar
# Imprimeix les paraules que comencin amb'par'
, acaben en 't'
, i poden tenir 'en'
o 'ro'
al mig, sense importar si estan en majúscules o minúscules.
$ echo 'par apartment PARROT parent' | grep -ioE 'par(en|ro)?t'
part PARROT Parent
# Imprimeix coincidència quan hi ha text acotat
$ echo 'Disfruto practicant exercicis de "bash" i "R"' | grep -oE '"[^"]+"'
"bash" "R"
# Línies de 8 caràcters que tenen les mateixes 3 lletres minúscules al principi i al final
$ grep -xE '([a-z]{3})..\1' /usr/share/dict/words
mesdames respires restores testates