Ejecutar expresiones regulares dentro de una declaración de caso en Bash

Abdullah Bukhari 15 febrero 2024
  1. Introducción a las expresiones regulares
  2. La necesidad de habilitar la coincidencia de cadenas complejas en Bash
  3. Coincidencia de cadenas usando Regex en una estructura Caso
  4. Coincidencia de cadenas usando Regex en una estructura If-Else
Ejecutar expresiones regulares dentro de una declaración de caso en Bash

Este artículo explora las expresiones regulares, su sintaxis básica y cómo ejecutarlas con una estructura case y una estructura if-else en Bash.

Introducción a las expresiones regulares

Las expresiones regulares, también conocidas como regex o regexp, son una secuencia de caracteres que se utilizan para hacer coincidir texto/cadena. El regex puede ser muy poderoso y ahorrará mucho tiempo cuando necesite analizar toneladas de datos.

Aunque Bash no usa regex, usa la coincidencia de cadenas, cuya sintaxis es similar a regex. El siguiente script lo ayudará a sentirse cómodo con los conceptos básicos de la coincidencia de cadenas con Bash.

?(a pattern list)
# Matches exactly zero or one instance of the pattern

*(a pattern list)
# This matches zero or more instances of the pattern.

+(a pattern list)
# This matches one or more instances of the pattern.

@(a pattern list)
# This matches one of the enclosed patterns.

!(a pattern list)
# This matches any pattern except the one enclosed.

La valla de código anterior muestra la sintaxis básica de regex; si desea leer más sobre regex, visite este enlace.

La necesidad de habilitar la coincidencia de cadenas complejas en Bash

De forma predeterminada, puede ejecutar expresiones regulares simples en Bash; las expresiones regulares complicadas requerirán que habilite una opción de extglob. Los siguientes comandos le mostrarán cómo habilitar o deshabilitar extglob para permitirle ejecutar expresiones regulares complicadas.

shopt -s extglob # this command enables extglob and allows the execution of complicated regex
shopt -u extglob # this command disables extglob and disables execution of complicated regex

El extglob en el comando anterior significa globo extendido. Si se establece, se permiten las funciones de coincidencia de patrones complejas/avanzadas proporcionadas en la expansión del nombre de ruta.

Cabe señalar que es imposible saber si una expresión regular es complicada sin ejecutarla. Habilite la opción extglob para ahorrarse cualquier sufrimiento y ejecutar todos sus comandos sin preocupaciones.

Una pregunta que puede tener es cómo sabremos si el extglob está activado o desactivado. Consulte el siguiente comando como referencia.

shopt | grep extglob # displays status of extglob

Producción :

extglob off # displays this line if extglob is disabled
extglob on # displays this line if extglob is enabled

habilitando la coincidencia de cadenas complejas en bash

El comando anterior mostrará el estado del extglob, ya sea activado o desactivado.

Coincidencia de cadenas usando Regex en una estructura Caso

La coincidencia de cadenas (similar a regex) se puede hacer aún más poderosa con una estructura de caso, que nos gustaría usar para permitirnos analizar datos más complicados. Los siguientes comandos lo ayudarán a utilizar case en Bash.

case EXPRESSION in
Match_1)
STATEMENTS # run this statement if in matches match_1
;;
Match_2)
STATEMENTS # run this statement if in matches match_2
;;
Match_N)
STATEMENTS # run this statement if in matches match_N
;;
*)
STATEMENTS # otherwise, run this statement
;;
Esac # signals the end of the case statement to the kernel

El código anterior es la sintaxis genérica que utilizará en caso de que desee combinar la coincidencia de cadenas Bash con una estructura de caso.

Bash, por defecto, permite la coincidencia de patrones simples. Por ejemplo, ejecutará con éxito el siguiente comando Bash.

cat sh*
# the above command displays the contents of all files whose name begins #with sh to the monitor (or stdout)

Sin embargo, dado el siguiente comando (que utiliza una coincidencia de patrones complicada), obtendrá un error bash: error de sintaxis cerca del token inesperado '('.

cat +([0-9]) # this command displays contents of files whose names are
# entirely composed of numbers

error cuando extglob está deshabilitado

Si desea profundizar más en la coincidencia de cadenas en Bash, utilice el siguiente comando.

man bash # man is a short form of manual pages here

Las páginas del manual son una utilidad que se puede utilizar para encontrar información sobre cualquier comando Bash, llamada al sistema y mucho más.

Si está utilizando la coincidencia de cadenas con un caso en Bash, es una buena práctica declarar y definir primero una variable con la que comparará el patrón.

Usamos un caso con coincidencia de cadenas en el fragmento de comandos a continuación. Observe cómo hemos utilizado los conceptos básicos de coincidencia de cadenas para generar un potente algoritmo de coincidencia de cadenas.

Veamos los comandos.

# Remember to not forget to enable extglob
shopt -s extglob # enables extglob
shopt | grep extglob # checks if extglob is enabled

some_variable="rs-123.host.com"; # declare and define variable
case $some_variable in
ab-+([0-9])\.host\.com) echo "First 2 characters were ab"
;;
ks-+([0-9])\.host\.com) echo "First 2 characters were ks"
;;
cs-+([0-9])\.host\.com) echo "First 2 characters were cs"
;;
*)echo "unknown first 2 characters"
;;
esac;
# the above command will display the unknown first 2 characters as we
# don't have a match in the first three cases, so the last default one will #automatically be true

Producción :

unknown first 2 characters

Si analiza el comando de coincidencia de cadenas anterior, si los dos primeros caracteres son uno de (ab, ks, cs) y el siguiente carácter es un guión () seguido de cualquier número de dígitos y termina con .host.com, uno de los primeros tres casos será exitoso y se mostrará un mensaje apropiado.

Sin embargo, si este no es el caso, se ejecutará el valor predeterminado (es decir, el caso contrario) y obtendremos un mensaje: primeros 2 caracteres desconocidos.

Tenemos una solución más simple si encuentra que los comandos anteriores son demasiado complicados. El siguiente comando explica exactamente cómo.

some_variable="rs-123.host.com"; # declare and define variable
case $some_variable in
ab*.host.com) echo "First 2 characters were ab"
;;
# the command below stays the same

coincidencia de cadenas usando regex

El comando anterior hace lo mismo que la estructura de casos más complicada que usamos anteriormente.

Coincidencia de cadenas usando Regex en una estructura If-Else

Otra forma de codificar potentes algoritmos de coincidencia de cadenas es utilizarlos con una estructura if-else. Nos gustaría usar esto para analizar datos más complicados.

El siguiente comando Bash lo guía a través de la sintaxis de una estructura if-else.

if expression1
then
task1
elif expression2
then
task2
else
task3
fi # signals ending of if else structure

Trabajar la estructura if-else es fácil; Primero, evaluamos la primera expresión.

Si es true, ejecutamos tarea 1. De lo contrario, consideramos la segunda expresión.

Si es true, ejecute la tarea 2. Ejecute tarea3 de lo contrario.

Ahora que se siente cómodo con la sintaxis de una estructura if-else, vamos a replicar el comando utilizado en la estructura case a una estructura if-else equivalente. Consulte el siguiente comando para hacer eso.

# Remember to not forget to enable extglob
shopt -s extglob # enables extglob
shopt | grep extglob # checks if extglob is enabled

some_variable="rs-123.host.com"; # declare and define variable
if expr "$some_variable" : ‘ab-+([0-9])\.host\.com’ >/dev/null; then echo "First 2 characters were ab"
elif expr "$some_variable" : ‘ks-+([0-9])\.host\.com’ >/dev/null; then echo "First 2 characters were ks"
elif expr "$some_variable" : ‘cs-+([0-9])\.host\.com’ >/dev/null; then echo "First 2 characters were cs"
else echo "unknown first 2 characters"
fi

# the above command will display the unknown first 2 characters as we
# don't have a match in the first three cases, so the last default one will #automatically be true

Producción :

unknown first 2 characters

coincidencia de cadenas usando expresiones regulares en un if else

El comando anterior es el equivalente if-else de la estructura case que usamos anteriormente.

Artículo relacionado - Bash Regex