Introducción a GREP y expresiones regulares

Introducción a GREP y expresiones regulares

Objetivo

Después de leer este tutorial, debería poder comprender cómo funciona el comando GREP y cómo usarlo con expresiones regulares básicas y extendidas.

Dificultad

FÁCIL

Introducción

Grep es una de las herramientas más útiles que podemos usar al administrar una máquina basada en UNIX: su trabajo es buscar un patrón dado dentro de uno o más archivos y devolver las coincidencias existentes.

En este tutorial veremos cómo usarlo, y examinaremos también sus variantes: municipal y fgrep. Pondremos este extracto realmente famoso del libro "El señor de los anillos" en un archivo, y lo usaremos como objetivo para nuestros ejemplos:

Tres anillos para los reyes de élficos debajo del cielo, siete para los dwarf-lords en sus salones de piedra, nueve para hombres mortales condenados a morir, uno para el Señor Oscuro en su oscuro trono en la tierra de Mordor donde se encuentran las sombras. Un anillo para gobernarlos a todos, un anillo para encontrarlos, un anillo para traerlos a todos, y en la oscuridad los ata, en la tierra de Mordor donde se encuentran las sombras. 

Se llamará al archivo lotr.TXT.

Variantes GREP

En la introducción hablamos de dos variantes GREP: municipal y fgrep. Estas variantes están realmente en desacuerdo, ya que son el equivalente a ejecutar GREP con el -mi y -F opciones respectivamente. Antes de comenzar a explicar en lo que esas variantes son diferentes del original, debemos examinar el comportamiento de GREP predeterminado al usar expresiones regulares.

El modo de expresión regular básico

Una expresión regular es un patrón construido siguiendo reglas específicas para que coincida con una cadena o múltiples cadenas. Por defecto, GREP usa lo que llama Bre o expresiones regulares básicas: en este modo, solo están disponibles algunos metabarificadores (caracteres con un significado especial dentro de una expresión regular).

Como primer ejemplo, intentaremos usar GREP para que coincida con una cadena muy simple, la palabra "mortal". La sintaxis GREP es muy simple: invocamos el programa que proporciona el patrón para que coincida como el primer argumento, y el archivo de destino como el segundo:

$ Grep Mortal Lotr.TXT


El comando anterior no devuelve coincidencias, aunque la palabra "mortal" aparece en el texto: esto se debe a que por defecto Grep realiza una búsqueda en distingue mayúsculas y minúsculas modo, entonces, dado que la palabra "mortal" está en mayúscula, no coincide con el patrón que proporcionamos. Para superar este problema y realizar una búsqueda más "genérica", podemos usar el -i opción (abreviatura de --ignorar caso, lo que hace que Grep ignore las distinciones del caso:

$ grep -i mortal lotr.TXT

Esta vez el comando produce la siguiente salida (la coincidencia real se resalta en rojo):

Nueve para hombres mortales condenados a morir,

Una cosa importante a tener en cuenta es que, por defecto, GREP devuelve la línea completa en la que se encuentra la coincidencia. Sin embargo, este comportamiento puede modificarse utilizando el -O opción o su versión larga --solo coincidencia. Al usar esta opción, solo se imprime la coincidencia en sí:

$ grep -o -i mortal lotr.txt mortal 

Otro cambio interesante que podemos usar es -norte, corto para --número de línea. Cuando se usa esta opción, el número de líneas donde se encuentra una coincidencia se incluye en la salida GREP. Este comando:

$ grep -n -i mortal lotr.TXT

Produce la siguiente salida:

3: Nueve para hombres mortales condenados a morir

Dónde 3 es el número de la línea en la que se encuentra la coincidencia.

¿Qué pasa si solo queremos obtener el número real de coincidencias encontradas, en lugar de las coincidencias en sí mismas?? GREP tiene una opción dedicada para obtener este resultado: -C, o --contar. El uso del comando anterior con esta opción devuelve la siguiente salida:

1

Que es, como se esperaba, el número de coincidencias que se encuentran en el texto.

Meta-carácter básicos

Es hora de realizar una búsqueda un poco más elaborada. Ahora queremos encontrar todas las líneas que comienzan con la letra "O". Incluso cuando trabajan con expresiones regulares básicas, podemos usar el ^ personaje que coincida con la cadena vacía al comienzo de una línea:



$ Grep -i ^o Lotr.TXT

Como se esperaba, el resultado del comando es:

Uno para el Señor Oscuro en su trono oscuro, un anillo para gobernarlos a todos, un anillo para encontrarlos, un anillo para traerlos a todos, y en la oscuridad atarlos, 

Eso fue bastante fácil. Ahora supongamos que queremos restringir aún más nuestra búsqueda y encontrar todas las líneas que comienzan con una "O" y terminan con un "," personaje. Podemos usar este ejemplo para introducir algunos otros metacturadores que podemos usar en modo regex básico:

$ Grep -i ^o.*, $ lotr.TXT

El comando de arriba de Linux devuelve exactamente lo que estábamos buscando:

 Un anillo para gobernarlos a todos, un anillo para encontrarlos, un anillo para traerlos a todos, y en la oscuridad los ata,  

Expliquemos lo que hicimos anteriormente. En primer lugar, usamos el -i opción para hacer que nuestro caso de búsqueda sea insensible, al igual que nosotros en los ejemplos anteriores, que utilizamos el ^ MetaCaracter, seguido de una "O", buscando líneas que comienzan con esta letra.

Nosotros que usamos dos nuevos características meta: . y *. ¿Cuál es su papel en la expresión regular?? El . coincide con cualquier personaje, mientras que el * es un operador de repetición, que coincide con el elemento anterior cero o más veces. Finalmente especificamos el ,, Una coma, para ser igualada literalmente como el último personaje antes del final de la línea, coincidía con el ps característica.

Hacer coincidir un conjunto de caracteres con soportes cuadrados

En el ejemplo anterior usamos el punto, ., para especificar un patrón que coincida con cada personaje. ¿Qué pasaría si quisiéramos coincidir solo con un subconjunto de personajes?? Digamos, por ejemplo, queríamos encontrar todas las líneas que comenzaran con una "O" o una "I": para obtener tal resultado, podemos encerrar el conjunto de posibles caracteres que se combinarán con soportes cuadrados:

$ grep -i ^[o, i] lotr.TXT

El comando realizará una búsqueda insensible a la caja para una "O" o una "I" ubicada al comienzo de una línea. Aquí está el resultado:

Uno para el Señor Oscuro en su trono oscuro en la tierra de Mordor donde se encuentran las sombras. Un anillo para gobernarlos a todos, un anillo para encontrarlos, un anillo para traerlos a todos, y en la oscuridad los ata, en la tierra de Mordor donde se encuentran las sombras. 


Para que el patrón coincida, como lo está arriba, se debe encontrar al menos uno de los caracteres contenidos con soportes. Al especificar caracteres dentro de los soportes cuadrados, podemos especificar también un rango mediante el uso del - personaje. Entonces, por ejemplo, para que coincidan con los dígitos que podemos escribir [0-9]. De vuelta a nuestro texto, podemos usar esta sintaxis para que coincida con las líneas que comienzan con letras de "I" a "S" (insensible en caso):

$ grep -i ^[i -s] lotr.TXT

La salida del comando:

Siete para los Dwarf-Lords en sus salones de piedra, nueve para hombres mortales condenados a morir, uno para el Señor Oscuro en su oscuro trono en la tierra de Mordor donde se encuentran las sombras. Un anillo para gobernarlos a todos, un anillo para encontrarlos, un anillo para traerlos a todos, y en la oscuridad los ata, en la tierra de Mordor donde se encuentran las sombras. 

Lo anterior es casi el texto completo del poema: solo la primera línea, que comienza con la letra "t" (no incluida en el rango que especificamos), ha sido excluido del partido.

Dentro de los soportes cuadrados, podemos igualar también clases específicas de caracteres, utilizando predefinidos expresiones de soporte. Algunos ejemplos son:

  • [: Alnum:] - personajes alfanuméricos
  • [: dígito:] - dígitos de 0 a 9
  • [: inferior:] - letras minúsculas
  • [: superior:] - letras mayúsculas
  • [: en blanco:] - espacios y pestañas

El anterior no es una lista completa, pero puede encontrar fácilmente más ejemplos de expresiones de soporte consultando el manual de GREP.

Invertir el resultado de un partido

En los ejemplos anteriores, buscamos cada línea comenzando con una "O" o una "I", utilizando una búsqueda insensible. ¿Qué pasaría si quisiéramos obtener la salida opuesta, y así encontrar solo líneas sin coincidencias??

Grep nos permite obtener este resultado utilizando el -V opción (abreviatura de --invertir el partido). La opción, como se sugirió, le indica a GREP que devuelva la coincidencia invertida. Si ejecutamos el último comando que utilizamos anteriormente proporcionando esta opción, debemos obtener solo la primera línea del poema como salida. Verifiquemos:

$ grep -i -v ^[i -s] lotr.TXT

El resultado es tal como esperábamos, solo la primera línea del poema:

Tres anillos para los reyes de élficos debajo del cielo,

En nuestro ejemplo, podemos obtener el mismo resultado prefijo la lista de caracteres entre los soportes cuadrados con el ^ El carácter, que en este contexto asume un significado diferente, lo que hace que el patrón coincida solo con los caracteres no contenidos en la lista. Si corremos:

$ grep -i ^[ ^i -s] lotr.TXT

Recibimos el mismo resultado que antes:

Tres anillos para los reyes de élficos debajo del cielo,

Modo de expresión extendido

Mediante el uso municipal o grep con el -mi Opción (esta última es la forma recomendada), podemos acceder a otros metacturadores para que se utilicen en expresiones regulares. Veamos.



Operadores de repeticiones avanzadas

Ya conocimos al * Operador de repetición que está disponible también en modo de expresión regular básico. Al usar expresiones extendidas, tenemos acceso a otros operadores de ese tipo:

  • ? - coincide con el elemento que lo precede uno o cero veces
  • + - coincide con el elemento anterior una o más veces

También podemos especificar más repeticiones granulares mediante el uso de la sintaxis de los aparatos rizados. Por ejemplo, el siguiente patrón coincide con cada ocurrencia de una doble "L":

Grep l 2 Lort.TXT

La salida del comando anterior es:

Siete para los Dwarf-Lords en sus salones de piedra, un anillo para gobernarlos a todos, un anillo para encontrarlos, un anillo para traerlos a todos, y en la oscuridad atarlos, 

Con la misma sintaxis podemos especificar un número mínimo de ocurrencias, utilizando X,, o todo un rango posible, usando x, y, dónde X y Y representar, respectivamente, el número mínimo y máximo de repeticiones del artículo anterior.

Alternancia

Cuando trabajamos con expresiones regulares extendidas, también tenemos acceso a la | Meta-caracter, también llamado inflijo operador. Al usarlo, podemos unir dos expresiones regulares, produciendo una expresión que coincida con cualquier cadena que coincida con expresiones alternativas.

Es importante notar que ambos lados del inflijo El operador siempre intentará ser igualado: esto significa que este operador no funciona como el condicional o operador, donde se evalúa el lado derecho solo si el lado izquierdo es falso: esto se puede verificar observando la salida del siguiente comando:

$ grep -n -e '^o | l 2' lotr.txt 2: siete para los adornos enanos en sus pasillos de piedra, 4: uno para el Señor Oscuro en su trono oscuro 6: un anillo para gobernarlos a todos, un anillo para encontrarlos, 7: un anillo para traerlos a todos, y en la oscuridad los atan, 

Observe la salida: cada línea que comienza con el capital "O", o que contiene una doble "L" se ha incluido en la salida. En líneas 6 y 7, Sin embargo, ambas expresiones en el lado izquierdo y derecho del inflijo El operador produjo una coincidencia. Esto, como se indicó anteriormente, significa que ambos lados del operador se evalúan y si ambos producen una coincidencia, se incluyen ambas coincidencias.

Fgrep

Si, por defecto, GREP admite operadores básicos de expresiones regulares y utilizando el -mi opción o municipal Podemos usar expresiones regulares extendidas, con el -F interruptor (abreviatura de huellas fijas) o fgrep, Podemos instruir al programa para que siempre interprete un patrón como una lista de cuerdas fijas.

Esto significa que las cuerdas siempre se intentan coincidir literalmente, y todos los metacturadores pierden su significado especial. Esto puede ser útil cuando se operan en un texto o una cadena que contiene muchos caracteres que pueden considerarse como operadores sin tener que escapar de ellos manualmente.

Pensamientos de cierre

En este tutorial aprendimos a conocer el grep comando unix. Vimos cómo podemos usarlo para encontrar coincidencias en un texto utilizando expresiones regulares y también examinamos el comportamiento de sus variantes: municipal y fgrep. Examinamos algunas opciones muy útiles como -i, que se puede usar para realizar búsquedas insensibles.

Finalmente realizamos un recorrido por algunos de los operadores de expresiones regulares más utilizados. Grep es definitivamente una de las herramientas del sistema más importantes y tiene una documentación muy exhaustiva: consultarlo siempre es una buena idea!

Tutoriales de Linux relacionados:

  • Una introducción a la automatización, herramientas y técnicas de Linux
  • Bash Regex avanzado con ejemplos
  • Mastering Bash Script Loops
  • Cosas para instalar en Ubuntu 20.04
  • Bucles anidados en guiones Bash
  • Expresiones regulares de Python con ejemplos
  • Mint 20: Mejor que Ubuntu y Microsoft Windows?
  • Bash regexps para principiantes con ejemplos
  • Tutorial de depuración de GDB para principiantes
  • Manipulación de Big Data para diversión y ganancias Parte 3