GNU/Linux >> Tutoriales Linux >  >> Linux

Introducción a las expresiones regulares:un ejemplo

En Introducción a las expresiones regulares , cubrí qué son y por qué son útiles. Ahora, necesitamos un ejemplo del mundo real para usar como herramienta de aprendizaje. Aquí hay uno que encontré hace varios años.

Este ejemplo destaca el poder y la flexibilidad de la línea de comandos de Linux, especialmente las expresiones regulares, por su capacidad para automatizar tareas comunes. He administrado varios servidores de listas durante mi carrera y todavía lo hago. La gente me envía direcciones de correo electrónico para agregar a esas listas. En más de un caso, he recibido una lista de nombres y direcciones de correo electrónico en formato de Microsoft Word para agregar a una de las listas.

La lista problemática

La lista en sí no era muy larga, pero era inconsistente en su formato. Aquí se muestra una versión abreviada de esa lista, con cambios de nombre y dominio:

Team 1	Apr 3 
Leader  Virginia Jones  [email protected]	
Frank Brown  [email protected]	
Cindy Williams  [email protected]	
Marge smith   [email protected] 
 [Fred Mack]   [email protected]	

Team 2	March 14
leader  Alice Wonder  [email protected]	
John broth  [email protected]	
Ray Clarkson  [email protected]	
Kim West    [email protected]	
[JoAnne Blank]  [email protected]	

Team 3	Apr 1 
Leader  Steve Jones  [email protected]	
Bullwinkle Moose [email protected]	
Rocket Squirrel [email protected]	
Julie Lisbon  [email protected]	
[Mary Lastware) [email protected]

La lista original tenía líneas adicionales, caracteres como corchetes y paréntesis que deben eliminarse, espacios en blanco como espacios y tabulaciones, y algunas líneas vacías. El formato requerido para agregar estos correos electrónicos a la lista es <first> <last> <[email protected]> . Nuestra tarea es transformar esta lista en un formato utilizable por el software de listas de correo.

Era obvio que necesitaba manipular los datos para convertirlos en un formato aceptable para ingresar a la lista. Es posible utilizar un editor de texto o un procesador de texto como LibreOffice Writer para realizar los cambios necesarios en este pequeño archivo. Sin embargo, la gente me envía archivos como este con bastante frecuencia, por lo que se convierte en una tarea ardua usar un procesador de textos para realizar estos cambios. A pesar de que Writer tiene una buena función de búsqueda y reemplazo, cada carácter o cadena debe reemplazarse individualmente y no hay forma de guardar búsquedas anteriores.

Writer tiene una potente función de macros, pero no estoy familiarizado con ninguno de sus dos idiomas:LibreOffice Basic o Python. Sé programación de shell Bash.

Hice lo que es natural para un administrador de sistemas:automaticé la tarea. Lo primero que hice fue copiar los datos de la dirección en un archivo de texto para poder trabajar en él usando herramientas de línea de comandos. Después de unos minutos de trabajo, desarrollé el programa de línea de comandos Bash que se muestra en el artículo anterior:

$ 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" | awk '{print $1" "$2" <"$3">"}' > addresses.txt

Este código produjo el resultado deseado como el archivo addresses.txt . Utilicé mi enfoque normal para escribir programas de línea de comandos como este construyendo la tubería un comando a la vez.

Desglosemos esta canalización en sus partes componentes para ver cómo funciona y cómo encaja. Todos los experimentos de esta serie deben realizarse como un usuario sin privilegios. También hice esto en una máquina virtual que creé para probar:studentvm1 .

El archivo de muestra

Primero, necesitamos crear el archivo de muestra. Crea un directorio llamado testing en su máquina local y luego copie el texto a continuación en un nuevo archivo de texto llamado Experiment_6-1.txt , que contiene las tres entradas de equipo que se muestran arriba.

Team 1  Apr 3 
Leader  Virginia Jones  [email protected]
Frank Brown  [email protected]
Cindy Williams  [email protected]
Marge smith   [email protected] 
 [Fred Mack]   [email protected]  

Team 2  March 14
leader  Alice Wonder  [email protected]
John broth  [email protected]  
Ray Clarkson  [email protected]
Kim West    [email protected] 
[JoAnne Blank]  [email protected]

Team 3  Apr 1 
Leader  Steve Jones  [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]  
Julie Lisbon  [email protected]

Eliminar líneas innecesarias con grep

Las primeras cosas que veo que se pueden hacer son un par de cosas fáciles. Dado que los nombres y las fechas de los equipos están solos en las líneas, podemos usar lo siguiente para eliminar aquellas líneas que tienen la palabra "Equipo:"

[student@studentvm1 testing]$  cat Experiment_6-1.txt | grep -v Team

No reproduciré los resultados de cada etapa de la construcción de este programa Bash, pero debería poder ver los cambios en el flujo de datos a medida que aparecen en STDOUT, la sesión de la terminal. No lo guardaremos en un archivo hasta el final.

En este primer paso para transformar el flujo de datos en uno utilizable, usamos el grep comando con un patrón literal simple, Team . Los literales son el tipo de patrón más básico que podemos usar como expresión regular, porque solo hay una única coincidencia posible en el flujo de datos que se busca, y esa es la cadena Team .

Necesitamos descartar líneas vacías, para que podamos usar otro grep declaración para eliminarlos. Encuentro que encerrar la expresión regular para el segundo grep El comando entre comillas asegura que se interprete correctamente:

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$"
Leader  Virginia Jones  [email protected]
Frank Brown  [email protected]
Cindy Williams  [email protected]
Marge smith   [email protected] 
 [Fred Mack]   [email protected]  
leader  Alice Wonder  [email protected]
John broth  [email protected]  
Ray Clarkson  [email protected]
Kim West    [email protected] 
[JoAnne Blank]  [email protected]
Leader  Steve Jones  [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]  
Julie Lisbon  [email protected]
[Mary Lastware) [email protected]
[student@studentvm1 testing]$

La expresión "^\s*$" ilustra anclas y usa la barra invertida (\) como un carácter de escape para cambiar el significado de una "s" literal (en este caso) a un metacarácter que significa cualquier espacio en blanco, como espacios, tabulaciones u otros caracteres que no se pueden imprimir. No podemos ver estos caracteres en el archivo, pero contiene algunos de ellos.

El asterisco, también conocido como splat (*), especifica que debemos hacer coincidir cero o más de los caracteres de espacio en blanco. Esta adición coincidiría con varias pestañas, varios espacios o cualquier combinación de estos en una línea vacía.

Ver espacios en blanco adicionales con Vim

Luego, configuré mi editor Vim para mostrar espacios en blanco usando caracteres visibles. Haga esto agregando la siguiente línea a su propio ~.vimrc o al archivo global /etc/vimrc archivo de configuración:

set listchars=eol:$,nbsp:_,tab:<->,trail:~,extends:>,space:+

Luego, inicie, o reinicie, Vim.

He encontrado mucha información mala, incompleta y contradictoria en Internet en mis búsquedas sobre cómo hacer esto. La ayuda integrada de Vim tiene la mejor información, y la línea de datos que creé a partir de la anterior es una que funciona para mí.

Nota: En el siguiente ejemplo, los espacios regulares se muestran como +; las pestañas se muestran como < , <> , o <–> y rellene la longitud del espacio que cubre la pestaña. El carácter de fin de línea (EOL) se muestra como $ .

El resultado, antes de cualquier operación en el archivo, se muestra aquí:

Team+1<>Apr+3~$
[email protected]<-->$
[email protected]<---->$
[email protected]<--->$
[email protected]~$
+[Fred+Mack][email protected]<>$
$
Team+2<>March+14$
[email protected]<----->$
[email protected]<>$
[email protected]<-->$
[email protected]>$
[JoAnne+Blank][email protected]<---->$
$
Team+3<>Apr+1~$
[email protected]<-->$
[email protected]<--->$
[email protected]<>$
[email protected]<------>$
[Mary+Lastware)[email protected]$

Eliminar caracteres innecesarios con sed

Puede ver que hay muchos caracteres de espacio en blanco que deben eliminarse de nuestro archivo. También necesitamos deshacernos de la palabra "líder", que aparece dos veces y está en mayúscula una vez. Primero deshagámonos de "líder". Esta vez, usaremos sed (editor de flujo) para realizar esta tarea sustituyendo una nueva cadena, o una cadena nula en nuestro caso, por el patrón que coincide.

Agregando sed -e "s/[Ll]eader//" a la canalización hace esto:

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//"

En este sed comando, -e significa que la expresión entre comillas es un script que produce un resultado deseado. En la expresión, los s significa que esto es una sustitución. La forma básica de una sustitución es s/<regex>/<replacement string>/ , entonces /[Ll]eader/ es nuestra cadena de búsqueda.

El conjunto [Ll] coincide con L o l , entonces [Ll]eader coincide con leader o Leader . En este caso, la cadena de reemplazo es nula porque parece una barra diagonal doble sin caracteres ni espacios en blanco entre las dos barras (// ).

También eliminemos algunos de los caracteres extraños como []() eso no será necesario:

[student@studentvm1 testing]$ 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"

Hemos agregado cuatro nuevas expresiones al sed declaración. Cada uno elimina un solo carácter. La primera de estas expresiones adicionales es un poco diferente, porque la llave cuadrada izquierda ([ ) el carácter puede marcar el comienzo de un conjunto. Necesitamos escapar de la llave para asegurarnos de que sed lo interpreta correctamente como un carácter regular y no especial.

Ordenar con awk

Podríamos usar sed para eliminar los espacios iniciales de algunas de las líneas, pero el awk puede hacer eso, reordene los campos si es necesario y agregue el <> caracteres alrededor de la dirección de correo electrónico:

[student@studentvm1 testing]$ 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">"}'

El awk La utilidad es en realidad un poderoso lenguaje de programación que puede aceptar flujos de datos en su STDIN. Este hecho lo hace extremadamente útil en scripts y programas de línea de comandos.

El awk La utilidad funciona en campos de datos y el separador de campo predeterminado son espacios, cualquier cantidad de espacio en blanco. El flujo de datos que hemos creado hasta ahora tiene tres campos separados por espacios en blanco (<first> , <last> y <email> ):

awk '{print $1" "$2" <"$3">"}'

Este pequeño programa toma cada uno de los tres campos ($1 , $2 y $3 ) y los extrae sin espacios en blanco iniciales o finales. Luego los imprime en secuencia, agregando un solo espacio entre cada uno, así como el <> caracteres necesarios para incluir la dirección de correo electrónico.

Resumiendo

El último paso aquí sería redirigir el flujo de datos de salida a un archivo, pero eso es trivial, por lo que le dejo a usted que realice ese paso. No es realmente necesario que lo hagas.

Guardé el programa Bash en un archivo ejecutable y ahora puedo ejecutar este programa cada vez que recibo una nueva lista. Algunas de esas listas son bastante cortas, como la de este ejemplo. Otros han sido bastante largos, a veces contienen hasta varios cientos de direcciones y muchas líneas de "cosas" que no contienen direcciones para agregar a la lista.

Nota: Este artículo es una versión ligeramente modificada del Capítulo 6 del Volumen 2 de mi libro de Linux, Uso y administración de Linux:de cero a SysAdmin, que se publicará en Apress a finales de 2019.


Linux
  1. Comenzando con Zsh

  2. Comenzando con ls

  3. Primeros pasos con PostgreSQL en Linux

  4. Primeros pasos con SSH en Linux

  5. Cómo:Introducción a Ansible

Primeros pasos con GitHub

Primeros pasos con el administrador de paquetes de Nix

Primeros pasos con systemctl

Primeros pasos con cPanel

Primeros pasos con SiteApps

Primeros pasos con el comando Tar