GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo usar una variable como condición de caso?

Estoy tratando de usar una variable que consta de diferentes cadenas separadas con un | como un case prueba de declaraciones Por ejemplo:

string=""foo"|"bar""
read choice
case $choice in
    $string)
        echo "You chose $choice";;
    *)
        echo "Bad choice!";;
esac

Quiero poder escribir foo o bar y ejecuta la primera parte del case declaración. Sin embargo, tanto foo y bar llévame al segundo:

$ foo.sh
foo
Bad choice!
$ foo.sh
bar
Bad choice!

Usando "$string" en lugar de $string No hace diferencia. Tampoco usar string="foo|bar" .

Sé que puedo hacerlo de esta manera:

case $choice in
    "foo"|"bar")
        echo "You chose $choice";;
    *)
        echo "Bad choice!";;
esac

Puedo pensar en varias soluciones, pero me gustaría saber si es posible usar una variable como un case condición en bash. ¿Es posible y, de ser así, cómo?

Respuesta aceptada:

El manual de bash dice:

caso palabra en [ [(] patrón [ | patrón ] … ) lista;; ] … esac

Cada patrón examinado se expande usando expansión de tilde, expansión de parámetros y variables, sustitución aritmética, sustitución de comandos y sustitución de procesos.

Sin «expansión de nombre de ruta»

Por lo tanto:un patrón NO se expande con «Expansión de nombre de ruta».

Por lo tanto:un patrón NO puede contener “|” en el interior. Solo:se podrían unir dos patrones con el “|”.

Esto funciona:

s1="foo"; s2="bar"    # or even s1="*foo*"; s2="*bar*"

read choice
case $choice in
    $s1|$s2 )     echo "Two val choice $choice"; ;;  # not "$s1"|"$s2"
    * )           echo "A Bad  choice! $choice"; ;;
esac

Uso de «Globbing extendido»

Sin embargo, word coincide con pattern utilizando las reglas de «Expansión de nombre de ruta».
Y «Extendido Globbing» aquí, aquí y aquí permite el uso de patrones alternos (“|”).

Esto también funciona:

shopt -s extglob

string='@(foo|bar)'

read choice
    case $choice in
        $string )      printf 'String  choice %-20s' "$choice"; ;;&
        $s1|$s2 )      printf 'Two val choice %-20s' "$choice"; ;;
        *)             printf 'A Bad  choice! %-20s' "$choice"; ;;
    esac
echo

Contenido de cadena

El siguiente script de prueba muestra que el patrón que coincide con todas las líneas que contienen foo o bar cualquier lugar es '*$(foo|bar)*' o las dos variables $s1=*foo* y $s2=*bar*

Guión de prueba:

shopt -s extglob    # comment out this line to test unset extglob.
shopt -p extglob

s1="*foo*"; s2="*bar*"

string="*foo*"
string="*foo*|*bar*"
string='@(*foo*|*bar)'
string='*@(foo|bar)*'
printf "%sn" "$string"

while IFS= read -r choice; do
    case $choice in
        "$s1"|"$s2" )   printf 'A first choice %-20s' "$choice"; ;;&
        $string )   printf 'String  choice %-20s' "$choice"; ;;&
        $s1|$s2 )   printf 'Two val choice %-20s' "$choice"; ;;
        *)      printf 'A Bad  choice! %-20s' "$choice"; ;;
    esac
    echo
done <<-_several_strings_
f
b
foo
bar
*foo*
*foo*|*bar*
"foo"
"foo"
afooline
onebarvalue
now foo with spaces
_several_strings_

Linux
  1. Cómo usar BusyBox en Linux

  2. Cómo usar BUSCAR en Linux

  3. Cómo usar el comando Su en Linux

  4. ¿Cómo usar sed para reemplazar la variable de un archivo de configuración?

  5. En Puppet, ¿cómo protegería una variable de contraseña (en este caso, una contraseña de MySQL)?

Cómo usar Telnet en Windows

Cómo usar Instagram en la terminal

Cómo usar el comando PS

Cómo usar el comando SUPERIOR

¿Cómo usar el HUD?

Cómo usar FTP