En Introducción a las expresiones regulares , presenté el concepto y los conceptos básicos, y luego en Primeros pasos con las expresiones regulares:un ejemplo , analizamos un ejemplo que limpia listas de nombres y direcciones de correo electrónico para que sean consistentes y analizables. Después de nuestra inmersión en Regex y grep:flujo de datos y bloques de construcción , donde entramos en más detalles sobre las expresiones regulares, ahora es el momento de explorar formas en las que podemos acortar y simplificar el programa de línea de comandos del primer ejemplo. Nos centraremos aquí en grep
y sed
.
Ejemplo:Simplificando el programa de listas de correo
Primero, echemos un vistazo a nuestro primer ejemplo, donde creamos el siguiente programa de interfaz de línea de comandos (CLI):
cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g" | awk '{print $1" "$2" <"$3">"}'
Es posible que encuentre las expresiones regulares más fáciles de leer en este punto, pero este programa se puede simplificar.
gato y grep
Empecemos centrándonos en el principio del comando, que implica cat
y grep
:
cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$"
Podemos combinar los dos grep
declaraciones, que originalmente se ven así:
| grep -v Team | grep -v "^\s*$"
Consejo: Cuando el STDOUT de grep
no se canaliza a través de otra utilidad, y cuando se usa un emulador de terminal que admite color, las coincidencias de expresiones regulares se resaltan en el flujo de datos de salida.
El comando revisado es:
grep -vE "Team|^\s*$"
Aquí, hemos agregado la E
opción, que especifica expresiones regulares extendidas. Según el grep
página man:
"En GNU grep no hay diferencia en la funcionalidad disponible entre las sintaxis básica y extendida".
Esta afirmación no es estrictamente cierta, porque nuestra nueva expresión combinada falla sin la E
opción. Ejecute lo siguiente para ver los resultados:
[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -vE "Team|^\s*$"
Pruébalo sin la E
opción.
Ahora, echemos un vistazo a cat
. El grep
La herramienta también puede leer datos de un archivo, por lo que podemos eliminar el cat
comando completamente:
[student@studentvm1 testing]$ grep -vE "Team|^\s*$" Experiment_6-1.txt
Este cambio y el anterior juntos nos dejan con el siguiente programa CLI algo simplificado:
grep -vE "Team|^\s*$" Experiment_6-1.txt | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g" | awk '{print $1" "$2" <"$3">"}'
Este comando es más corto, más conciso y se ejecutará más rápido porque grep
solo necesita analizar el flujo de datos una vez.
sed
También podemos simplificar el sed
dominio. El sed
La utilidad no solo permite buscar texto que coincida con un patrón de expresiones regulares, sino que también puede modificar, eliminar o reemplazar el texto coincidente. Yo uso sed
en la línea de comandos y en los scripts de shell de Bash como una forma rápida y sencilla de localizar texto y modificarlo. El nombre sed
significa editor de flujo porque opera en flujos de datos de la misma manera que otras herramientas que pueden transformar un flujo de datos. La mayoría de esos cambios implican seleccionar líneas específicas del flujo de datos y pasarlas a otro programa transformador.
grep
filtrar programas , porque filtran las líneas no deseadas del flujo de datos. Prefiero el término transformadores , porque herramientas como sed
y awk
hacer más que solo filtrar. Pueden probar contenido para varias combinaciones de cadenas y alterar el contenido coincidente de muchas maneras diferentes. Herramientas como sort
, head
, tail
, uniq
, fmt
, y más, todos transforman el flujo de datos de alguna manera.
Ya hemos visto sed
en acción, pero ahora, con una comprensión de las expresiones regulares, podemos analizar y comprender mejor nuestro uso anterior. Es posible combinar cuatro de las cinco expresiones utilizadas en el sed
comando en una sola expresión. El sed
comando ahora tiene dos expresiones en lugar de cinco:
sed -e "s/[Ll]eader//" -e "s/[]()\[]//g"
Este formato hace que sea un poco difícil de entender la expresión más compleja. Tenga en cuenta que no importa cuántas expresiones un solo sed
contiene el comando, el flujo de datos solo se analiza una vez para que coincida con todas las expresiones.
Examinemos la expresión revisada más de cerca:
-e "s/[]()\[]//g"
Por defecto, sed
interpreta todos los [
caracteres como el comienzo de un conjunto, y el último ]
carácter como el final de ese conjunto. Entonces, en el código anterior, el primer [
y el último ]
contiene el conjunto. El ]
interviniente los caracteres no se interpretan como metacaracteres.
Ya que necesitamos hacer coincidir [
como carácter literal para eliminarlo del flujo de datos y sed
normalmente interpreta [
como metacarácter, necesitamos escaparlo para que se interprete como un ]
literal . Ahí es donde la barra invertida (\
) entra, dándonos \[
en el medio.
Conectemos esta nueva versión al script CLI y probémoslo:
[student@studentvm1 testing]$ grep -vE "Team|^\s*$" Experiment_6-1.txt | sed -e "s/[Ll]eader//" -e "s/[]()\[]//g"
Sé lo que está preguntando:"¿Por qué no colocar el \[
después del [
que abre el conjunto, y antes del ]
personaje?" Pruébalo como lo hice yo:
[student@studentvm1 testing]$ grep -vE "Team|^\s*$" Experiment_6-1.txt | sed -e "s/[Ll]eader//" -e "s/[\[]()]//g"`
Creo que eso debería funcionar, pero no es así. Pequeños resultados inesperados como este dejan en claro que debemos tener cuidado y probar cada expresión regular cuidadosamente para asegurarnos de que realmente hace lo que pretendemos.
Después de algunos experimentos propios, descubrí que la llave cuadrada izquierda escapada \[
funciona bien en todas las posiciones de la expresión excepto en la primera. Este comportamiento se observa en el grep
página de manual, que probablemente debería haber leído primero. Sin embargo, encuentro que la experimentación refuerza las cosas que leo, y generalmente descubro cosas más interesantes de lo que estaba buscando.
Agregando el último componente, el awk
declaración, nuestro programa optimizado se ve así y los resultados son exactamente lo que queremos:
[student@studentvm1 testing]$ grep -vE "Team|^\s*$" Experiment_6-1.txt | sed -e "s/[Ll]eader//" -e "s/[]()\[]//g" | awk '{print $1" "$2" <"$3">"}'
Otras herramientas que implementan expresiones regulares
Muchas herramientas de Linux implementan expresiones regulares. La mayoría de esas implementaciones son muy similares a las de awk
, grep
y sed
, por lo que debería ser fácil aprender las diferencias. Aunque no hemos analizado en detalle awk, es un poderoso lenguaje de procesamiento de texto que también implementa expresiones regulares.
La mayoría de los editores de texto más avanzados usan expresiones regulares. Vim, gVim, Kate y GNU Emacs no son excepciones. El less
La utilidad implementa expresiones regulares, al igual que la función de búsqueda y reemplazo de LibreOffice Writer.
Los lenguajes de programación como Perl, awk y Python también contienen implementaciones de expresiones regulares, lo que los hace muy adecuados para escribir herramientas para la manipulación de texto.
Recursos
He encontrado algunos recursos excelentes para aprender sobre expresiones regulares. Hay más de los que he enumerado aquí, pero estos son los que he encontrado particularmente útiles:
- El
grep
La página de manual tiene una buena referencia pero no es apropiada para aprender sobre expresiones regulares. - El libro de O'Reilly, Dominar las expresiones regulares , de Jeffrey E. F. Friedl, es un buen tutorial y referencia para las expresiones regulares. Lo recomiendo para cualquier persona que sea o quiera ser un administrador de sistemas de Linux porque usará expresiones regulares.
- El libro de O'Reilly sed &awk:UNIX Power Tools , de Arnold Robbins y Dale Dougherty, es otra buena. Cubre estas dos poderosas herramientas y también tiene una excelente discusión sobre las expresiones regulares.
También hay algunos buenos sitios web que pueden ayudarlo a aprender acerca de las expresiones regulares y que brindan ejemplos de expresiones regulares interesantes y útiles al estilo de un libro de cocina. Hay algunos que piden dinero a cambio de usarlos. Jason Baker, mi revisor técnico de los volúmenes 1 y 2 de mi Uso y administración de Linux El curso sugiere regexcrossword.com como una buena herramienta de aprendizaje.
Resumen
Esta serie ha proporcionado una breve introducción al complejo mundo de las expresiones regulares. Hemos explorado la implementación de expresiones regulares en grep
utilidad con la profundidad suficiente para darle una idea de algunas de las cosas asombrosas que se pueden lograr con expresiones regulares. También hemos analizado varias herramientas y lenguajes de programación de Linux que también implementan expresiones regulares.
¡Pero no te equivoques! Solo hemos arañado la superficie de estas herramientas y de las expresiones regulares. Hay mucho más que aprender y, como puede ver, hay algunos recursos excelentes para hacerlo.
Nota: Este artículo es una versión ligeramente modificada del Capítulo 6 del Volumen 2 de mi curso de autoaprendizaje de Linux, "Uso y administración de Linux:de cero a SysAdmin", que saldrá de Apress a finales de 2019.