Uso de case en Shell Script

La sentencia case ... esac permite ejecutar un bloque de código u otro en función del valor de una variable.

Es muy útil para evitar tener que anidar varios if.

Supongamos que queremos hacer un script  que le indiquemos un número romano y queremos que nos devuelva su valor en números árabes. Como es un ejemplo para ilustrar la diferencia entre encadenar varios if y luego ver su equivalente a case, nos vamos a limitar a que indique sólo una letra.

Si lo hacemos con if:

#!/bin/bash

read -N 1 -p "De qué número romano (I, V, X, L, C, D, M) quieres saber su valor: " roman
echo ""

if [ $roman == "I" ] || [ $roman == "i" ]
then
    echo 1
elif [ $roman == "V" ] || [ $roman == "v" ]
then
    echo 5
elif [ $roman == "X" ] || [ $roman == "x" ]
then
    echo 10 
elif [ $roman == "L" ] || [ $roman == "l" ]
then
    echo 50
elif [ $roman == "C" ] || [ $roman == "c" ]
then
    echo 100
elif [ $roman == "D" ] || [ $roman == "d" ]
then
    echo 500
elif [ $roman == "M" ] || [ $roman == "m" ]
then
    echo 100
else
    echo Número incorrecto
    echo ""
    exit 1
fi
echo ""
exit 0

Y ahora vamos a hacerlo con case:

#!/bin/bash

read -N 1 -p "De qué número romano (I, V, X, L, C, D, M) quieres saber su valor: " roman
echo ""

case $roman in
    "I" | "i")
        echo 1
        ;;
    "V" | "v")
        echo 5
        ;;
    "X" | "x")
        echo 10 
        ;;
    "L" | "l")
        echo 50
        ;;
    "C" | "c")
        echo 100
        ;;
    "D" | "d")
        echo 500
        ;;
    "M" | "m")
        echo 1000
        ;;
    *)
        echo Número incorrecto
        echo ""
        exit 1
esac
echo ""
exit 0

No ahorramos líneas, pero ganamos legibilidad, que es fundamental para programar bien. Recordemos que en nuestro día a día como desarrolladores pasamos mucho más tiempo leyendo código que escribiendo, por lo que todo lo que sea facilitar nuestro trabajo futuro o el trabajo en equipo es importantísimo.

Ahora vamos a ver qué es cada una de las partes de esta estructura:

Primero necesitamos una variable con un valor. Lo hemos pedido con read y lo hemos asignado a la variable roman.
Con case $roman in comenzamos la estructura case en la que se ejecutará uno u otro bloque en función del valor de la variable indicada.
La comparación "I" | "i") compara el valor de la variable con los valores indicados. Si coincide, ejecuta el código siguiente hasta que encuentra ;; o esac (lo primero que encuentre). Con | le decimos que se ejecute si uno u otro es igual al valor de la variable. Si en lugar de dos valores, le hubiéramos querido indicar sólo uno, lo hubiéramos hecho con "I")
Para indicar el final de un bloque de código y romper la ejecución de ese bloque de código usamos ;;.
Con *) indicamos que se ejecute ese bloque en caso de que el valor de la variable no coincida con ninguno de los anteriores. Equivalente a else en un if.
esac cierra el bloque case.
Veamos otro ejemplo sin pedir datos al usuario, sino capturándolo con la ejecución de un comando y en lugar de distintas opciones para ejecutar un bloque de código, una sola opción:

#!/bin/bash

day=$(date +%u)

case $day in
    1)
        echo $USER, hoy es lunes, no te olvides de las tareas del comienzo de semana. 
        ;;
    2)
        echo Hoy es martes.
        ;;
    3)
        echo Miércoles.
        ;;
    4)
        echo Feliz jueves, $USER.
        ;;
    5)
        echo Es viernes, $USER. Revisa las tareas de cierre de semana para poder disfrutar del fin de semana.
        ;;
    6)
        echo Disfruta del sábado.
        ;;
    7)
        echo Pasa un feliz domingo.
        ;;
esac

Aquí guardamos en day el valor devuelto con date +%u gracias a day=$(date +%u)

Y comparamos día de hoy con los distintos valores posibles (de 1 a 7). En función del resultado, mostramos una u otra cosa por pantalla.

Como no hay más que 7 días por semana, no hace falta que indiquemos con *) qué ejecutar si el valor es distinto a los establecidos.

Un comentario en «Uso de case en Shell Script»

Deja una respuesta

Tu dirección de correo electrónico no será publicada.