
Estoy buscando un operador "in" que funcione así:
if [ "$1" in ("cat","dog","mouse") ]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
Obviamente es una declaración mucho más corta en comparación con, digamos, el uso de varias pruebas "o".
Respuesta1
Puedes usar case
...esac
$ cat in.sh
#!/bin/bash
case "$1" in
"cat"|"dog"|"mouse")
echo "dollar 1 is either a cat or a dog or a mouse"
;;
*)
echo "none of the above"
;;
esac
Ex.
$ ./in.sh dog
dollar 1 is either a cat or a dog or a mouse
$ ./in.sh hamster
none of the above
Con ksh
, bash -O extglob
o zsh -o kshglob
, también puedes usar un patrón global extendido:
if [[ "$1" = @(cat|dog|mouse) ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
else
echo "none of the above"
fi
Con bash
, ksh93
o zsh
, también puedes usar una comparación de expresiones regulares:
if [[ "$1" =~ ^(cat|dog|mouse)$ ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
else
echo "none of the above"
fi
Respuesta2
No hay una prueba "in" en bash, pero sí una prueba de expresiones regulares (no en bourne):
if [[ $1 =~ ^(cat|dog|mouse)$ ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
Y generalmente escrito usando una variable (menos problemas con las comillas):
regex='^(cat|dog|mouse)$'
if [[ $1 =~ $regex ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
Para un shell Bourne más antiguo necesitas usar una coincidencia de casos:
case $1 in
cat|dog|mouse) echo "dollar 1 is either a cat or a dog or a mouse";;
esac
Respuesta3
Usar a case
está bien si tienes un conjunto fijo de mascotas con las que quieres comparar. Pero no funcionará si necesita crear el patrón en tiempo de ejecución, ya que case
no interpreta la alternancia dentro de los parámetros expandidos.
Esto coincidirá sólo con la cadena literal cat|dog|mouse
:
patt='cat|dog|mouse'
case $1 in
$patt) echo "$1 matches the case" ;;
esac
Sin embargo, puedes utilizar una variable con la coincidencia de expresión regular. Siempre que la variable no esté entre comillas, cualquier operador de expresiones regulares que contenga tiene significados especiales.
patt='cat|dog|mouse'
if [[ "$1" =~ ^($patt)$ ]]; then
echo "$1 matches the pattern"
fi
También puedes usar matrices asociativas. Comprobar si existe una clave en uno es lo más parecido a un in
operador que ofrece Bash. Aunque la sintaxis es un poco fea:
declare -A arr
arr[cat]=1
arr[dog]=1
arr[mouse]=1
if [ "${arr[$1]+x}" ]; then
echo "$1 is in the array"
fi
(${arr[$1]+x}
se expande x
si arr[$1]
está configurado; en caso contrario, se vacía.)
Respuesta4
grep
acercarse.
if echo $1 | grep -qE "^(cat|dog|mouse)$"; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
-q
para evitar cualquier salida a la pantalla (es más rápido de escribir que>/dev/null
).-E
para aspectos de expresiones regulares extendidas(cat|dog|mouse)
se necesita esto.^(cat|dog|mouse)$
coincide con cualquier línea que comience (^
) con gato, perro o ratón ((cat|dog|mouse)
) seguido del final de la línea ($
)