Procesamiento de texto con expresiones regulares

LinuxBeginner
Practicar Ahora

Introducción

Una expresión regular describe el texto según su estructura, en lugar de buscar una cadena exacta. El mismo lenguaje de patrones aparece en muchas herramientas de Linux, pero cada herramienta lo utiliza de una manera distinta: grep selecciona o extrae coincidencias, sed transforma un flujo y awk combina patrones con acciones que tienen en cuenta los campos.

Comenzará con anclas y clases de caracteres, continuará con la repetición y la extracción mediante expresiones extendidas, previsualizará las transformaciones antes de guardarlas y terminará seleccionando campos y calculando agregados. Los patrones aparecen entre comillas para que el shell pase los caracteres especiales a la herramienta de texto, en lugar de interpretarlos directamente.

Coincidir líneas con una estructura básica de expresiones regulares

En este paso, utilizará texto literal, anclas y clases de caracteres para describir posiciones dentro de una línea completa.

Inspeccione el archivo de práctica:

cd /home/labex/project/regex-lab
nl -ba contacts.txt

El texto literal coincide en cualquier posición de una línea:

grep 'active' contacts.txt

^ fija un patrón al principio de la línea y $ lo fija al final. Busque el registro de Alice y los registros que terminan en un número de dos dígitos:

grep '^Alice|' contacts.txt
grep '[0-9][0-9]$' contacts.txt

Dentro de los corchetes, una clase de caracteres coincide con un carácter. [ABC] significa A, B o C:

grep '^[ABC]' contacts.txt | tee abc-contacts.txt

Esto muestra los registros de Alice, Bob y Carol. Guarde también las coincidencias numéricas ancladas:

grep '[0-9][0-9]$' contacts.txt > two-digit-values.txt

Usar expresiones regulares extendidas y extraer coincidencias

En este paso, utilizará expresiones regulares extendidas para representar alternativas y repeticiones; después, extraerá únicamente la subcadena coincidente.

grep -E habilita operadores como + (uno o más), ? (cero o uno) y | (alternativa). Busque campos de estado completos con los valores active o pending:

cd /home/labex/project/regex-lab
grep -E '\|(active|pending)\|' contacts.txt

Puede construir un patrón similar al de una dirección de correo electrónico por partes:

  • [[:alnum:]._-]+ coincide con uno o más caracteres permitidos en la parte local;
  • @ es un carácter literal;
  • [[:alnum:].-]+ coincide con el cuerpo del dominio;
  • \.[[:alpha:]]{2,} coincide con un punto seguido de un sufijo de dos o más letras.

Utilice -o para mostrar únicamente las subcadenas coincidentes:

grep -Eo '[[:alnum:]._-]+@[[:alnum:].-]+\.[[:alpha:]]{2,}' contacts.txt | tee emails.txt

Numere las líneas coincidentes y cuente las direcciones extraídas:

grep -En '\|(active|pending)\|' contacts.txt
wc -l < emails.txt | tr -d ' ' > email-count.txt
cat email-count.txt

dave_at_example.com no coincide porque no contiene @.

Previsualizar transformaciones con Sed

En este paso, transformará un flujo con sed sin modificar la entrada.

Una sustitución tiene la forma s/pattern/replacement/flags. Sustituya solo la primera a de cada línea y, después, todas las a minúsculas mediante la marca g:

cd /home/labex/project/regex-lab
sed 's/a/A/' contacts.txt
sed 's/a/A/g' contacts.txt

Utilice otro delimitador cuando el texto contenga barras o cuando otro delimitador resulte más claro. Sustituya los dominios de correo electrónico por redacted.invalid:

sed -E 's#@[[:alnum:].-]+\.[[:alpha:]]{2,}#@redacted.invalid#g' contacts.txt

Las direcciones de sed seleccionan las líneas que reciben un comando. Aplique la sustitución del estado únicamente a las líneas que contienen el campo exacto |inactive|:

sed '/|inactive|/s/|inactive|/|disabled|/' contacts.txt | tee contacts-preview.txt

Confirme que el archivo original todavía contiene inactive:

grep '|inactive|' contacts.txt

Crear un archivo depurado con Sed

En este paso, combinará varios comandos de sed y guardará el flujo transformado en un archivo nuevo.

El encabezado de services.csv debe permanecer sin cambios. En las filas de datos, normalice warn a warning y añada el sufijo ms al último campo numérico. -e proporciona varios comandos, y la dirección 2,$ los limita a las líneas desde la 2 hasta el final:

cd /home/labex/project/regex-lab
sed -E -e '2,$ s/,warn,/,warning,/' -e '2,$ s/([0-9]+)$/\1ms/' services.csv | tee services-clean.csv

Aquí, los paréntesis capturan los dígitos finales y \1 reutiliza esa captura en la sustitución.

Compare los archivos original y nuevo:

diff -u services.csv services-clean.csv || true

El estado distinto de cero de diff es esperado porque la salida cambió intencionadamente; || true permite que una secuencia de comandos copiada continúe.

Seleccionar campos y calcular agregados con Awk

En este paso, utilizará awk cuando una tarea necesite tanto la estructura de los campos como cálculos.

-F, establece la coma como separador de entrada. Muestre el servicio y el estado únicamente para las filas de datos; NR es el número del registro actual:

cd /home/labex/project/regex-lab
awk -F, 'NR > 1 {print $1, $2}' services.csv

Seleccione las filas cuyo tercer campo numérico sea mayor que 200:

awk -F, 'NR > 1 && $3 > 200 {print $1, $3}' services.csv | tee slow-services.txt

Acumule un total y un recuento y, después, calcule un promedio en el bloque END. printf controla el formato numérico:

awk -F, 'NR > 1 {sum += $3; count++} END {printf "average_latency=%.1f\n", sum/count}' services.csv | tee latency-summary.txt

Los patrones de Awk determinan en qué registros se ejecuta una acción; los campos como $1 y $3 hacen que los cálculos estructurados sean fáciles de leer.

Resumen

Construyó patrones de expresiones regulares a partir de anclas, clases, alternativas y repeticiones; utilizó grep para seleccionar y extraer; utilizó sed para previsualizar y guardar transformaciones; y utilizó awk para seleccionar y calcular agregados teniendo en cuenta los campos. En el siguiente desafío, aplicará estas ideas sin recibir una secuencia completa de comandos.