1.11. Buscar, ordenar y asociar ficheros
1.11.2. «grep»
En Wikipedia puedes leer que grep
es una utilidad de línea de comando para buscar conjuntos de datos de texto plano en busca de líneas que coincidan con una expresión regular. Su nombre proviene del comando ed g/re/p
(globally search a regular expression and print, en castellano búsqueda global de una expresión regular e imprimir), que tiene el mismo efecto.
El comando grep
tiene muchas y variadas características, tanto es así que hay libros específicos al respecto. El uso más común es filtrar líneas de entrada usando expresiones regulares (en inglés, regexp).
Las opciones del comando grep
comúnmente utilizadas se muestran a continuación. Los ejemplos se discutirán en secciones posteriores.
-i
ignora la distinción entre mayúsculas y minúsculas al hacer coincidencias.-v
imprime solo las líneas que no coinciden.-n
agrega un prefijo de números de línea a las líneas de salida.-c
muestra solo el recuento de líneas de salida.-l
imprime solo los nombres de archivo que coinciden con la expresión dada.-L
imprime los nombres de archivo que no coinciden con el patrón.-w
hace coincidir el patrón solamente con palabras completas.-x
hace coincidir el patrón solamente con líneas completas.-F
interpreta el patrón como una cadena fija (es decir, no como una expresión regular).-o
imprime solamente las partes coincidentes.-A N
imprime la línea coincidente yN
líneas después de la línea coincidente.-B N
imprime la línea coincidente yN
líneas antes de la línea coincidente.-C N
imprime la línea coincidente yN
líneas antes y después de la línea coincidente.-m N
imprime un máximo deN
líneas coincidentes.-q
sin salida estándar, sale inmediatamente si se encuentra una coincidencia, útil en scripts.-s
suprime los mensajes de error, útil en scripts.-r
busca recursivamente todos los archivos en las carpetas de entrada especificadas (por defecto busca en el directorio actual).-R
como-r
, pero también sigue los enlaces simbólicos.--color=auto
resalta las porciones coincidentes, los nombres de archivo, los números de línea, etc. usando colores.
Búsqueda literal
Los siguientes ejemplos también serían adecuados con la opción -F
, ya que no utilizan expresiones regulares. El comando grep
está lo suficientemente bien diseñado como para hacer lo correcto en tales casos.
# Imprime líneas que contengan el string 'an'
. La opción \n genera una nueva línea
$ printf 'manzana\nbanana\nmango\nfigura\ntango\n' | grep 'an'
banana mango tango
# Imprime coincidencias sin distinción entre mayúsculas y minúsculas
$ printf 'Buho\nlagartija\buHoNero\ntres buhos\n' | grep -i 'buho'
Buho buHoNero tres buhos
# Imprime coincidencias de palabras completas
$ printf 'par basico\nparidad\n3-par' | grep -w 'par'
par basico 3-par
# Imprime coincidencias de líneas vacías y las cuenta
$ printf 'cielo\n\ntierra\n\n\n\ninfierno\n' | grep -cx ''
4
# Imprime coincidencias en una línea y las siguientes dos líneas (A, after)
$ printf 'red\ncactus\nsuculenta\npetunia\nesqueje' | grep -A2 'cactus'
cactus suculenta petunia
Expresiones regulares
De forma predeterminada, grep trata el patrón de búsqueda como una expresión regular básica (en inglés, Basic Regular Expression: BRE).
-G
se puede utilizar para especificar explícitamente que se necesita BRE.-E
habilitará expresiones regulares extendidas (en inglés, Extended Regular Expression: ERE). En GNU grep, BRE y ERE solo difieren en cómo se especifican los metacaracteres; no hay diferencia en las características.-F
hará que los patrones de búsqueda se traten literalmente.-P
habilitará expresiones regulares compatibles con Perl, si está disponible (PCRE, por sus siglas en inglés).
Las siguientes líneas son las referencias cuando se quieren usar expresiones regulares extendidas. Existen de varias clases:
Anclas
- ^ restringe la coincidencia al inicio de la cadena.
- $ restringe la coincidencia al final de la cadena.
- < restringe la coincidencia al inicio de palabra.
- > restringe la coincidencia al final de palabra.
- \b restringe la coincidencia al inicio/final de palabras.
- \B coincide donde \b no coincide.
Metacaracteres y cuantificadores
- . coincide con cualquier carácter, incluyendo el carácter de nueva línea.
- ¿ coincide 0 o 1 vez.
- * coincide 0 o más veces.
- + coincide 1 o más veces.
- {m,n} coincide de m a n
- {m,} coincide al menos m
- {,n} coincide hasta n veces (incluyendo 0 veces).
- {n} coincide exactamente n
Clases de caracteres
- [set123] coincide con cualquiera de estos caracteres una vez.
- [^set123] coincide, excepto con cualquiera de estos caracteres, una vez.
- [3-7AM-X] rango de caracteres desde 3 hasta 7, A, otro rango desde M hasta X.
- \w similar a [a-zA-Z0-9_] para coincidir con caracteres de palabras.
- \s similar a [ \t\n\r\f\v] para coincidir con caracteres de espacio en blanco.
- \W coincide con caracteres que no son de palabras.
- \S coincide con caracteres que no son de espacio en blanco.
- [[:digit:]] similar a [0-9] [[:alnum:]_] similar a \w
Se recomienda ver el manual del comando grep
para ser conscientes de la versatilidad de este comando.
Alternancia y agrupación
- Pat1|pat2|pat3 coincide con pat1 o pat2 o pat3.
- () agrupa patrones, a(b|c)d es lo mismo que abd|acd. También sirve como grupo de captura.
- \N referencia hacia atrás, proporciona la porción coincidente del N-ésimo grupo de captura.
- \1 referencia hacia atrás al primer grupo de captura.
- \2 referencia hacia atrás al segundo grupo de captura y así sucesivamente hasta \9.
En el manual de grep
se citan las diferencias entre BRE y ERE. En las expresiones regulares básicas, los metacaracteres ?, +, {, |, (y) pierden su significado especial; en su lugar, se utilizan las versiones con barra invertida \?,\ +, \{,\ |, \( y \).
# Imprime la coincidencia cuando el final de la línea termina con –ar
$ printf 'pedalear\ncorrer\nescribir\namar' | grep 'ar$'
pedalear amar
# Imprime las palabras que comienzan con 'par'
, terminan con 't'
, y pueden tener 'en'
o 'ro'
en el medio, sin importar si están en mayúsculas o minúsculas.
$ echo 'par apartment PARROT parent' | grep -ioE 'par(en|ro)?t'
part PARROT Parent
# Imprime coincidencia cuando hay texto acotado
$ echo 'Disfruto practicando ejercicios de "bash" y "R"' | grep -oE '"[^"]+"'
"bash" "R"
# Líneas de 8 caracteres que tienen las mismas 3 letras minúsculas al principio y al final
$ grep -xE '([a-z]{3})..\1' /usr/share/dict/words
mesdames respires restores testates