Estoy tratando de escribir un script en bash que verifique la validez de una entrada del usuario.
Quiero hacer coincidir la entrada (digamos variable x
) con una lista de valores válidos.
Lo que se me ocurrió en este momento es:
for item in $list
do
if [ "$x" == "$item" ]; then
echo "In the list"
exit
fi
done
Mi pregunta es si hay una forma más sencilla de hacer esto,
algo así como list.contains(x)
para la mayoría de los lenguajes de programación.
Adición:
Dicha lista es:
list="11 22 33"
mi código hará eco del mensaje solo para esos valores, ya que list
se trata como una matriz y no como una cadena, todas las manipulaciones de la cadena se validarán 1
mientras que yo quiero que falle.
[[ $list =~ (^| )$x($| ) ]] && echo 'yes' || echo 'no'
x=.
contains () { [[ "$1" =~ (^|[[:space:]])"$2"($|[[:space:]]) ]]; }
.[[ " $list " =~ " $x " ]] && echo 'yes' || echo 'no'
. es correcto suponiendo que el espacio es el separador y$x
no contiene espacioisIn()
para poder escribir primero el elemento en los parámetros. También se puedeecho
algo en lugar de utilizarexit
la siguiente manera:[[ $2 =~ (^|[[:space:]])$1($|[[:space:]]) ]] && echo 1 || echo 0
Para que pueda utilizar la función de esta manera:result=$(isIn "-t" "-o -t 45") && echo $result
Matvey tiene razón, pero debe citar $ x y considerar cualquier tipo de "espacios" (por ejemplo, nueva línea) con
entonces, es decir
termina entonces
o
Tenga en cuenta que debe usar
""
en caso de variables:fuente
$item
contiene caracteres especiales, como.
(pero la$list
variable probablemente necesita ser citada dentro de la prueba). Y la función se puede definir aún más simple:contains () { [[ "$1" =~ (^|[[:space:]])"$2"($|[[:space:]]) ]]; }
.list="aa bb xx cc ff"
yx="aa bb"
$list =~ (^|[[:space:]])"$item"($|[[:space:]])
. O, si tiene tiempo, me gustaría escuchar su explicación para esta expresión. Nota: Supongo que es una expresión regex (comienza con ^ etc.) pero no sé qué significa = ~. Así que me encantaría una explicación general: PLa solución más fácil de mi humilde opinión es anteponer y agregar la cadena original con un espacio y verificar con una expresión regular con
[[ ]]
esto no será falso positivo en valores con valores que contienen la aguja como una subcadena, por ejemplo, con un pajar
foo barbaz
.(El concepto es descaradamente robado del
hasClass()
método de JQuery )fuente
haystack="foo:bar"
y[[ ":$haystack:" = *:$needle:* ]]
qué tal si
puede verificar la salida o la
$?
línea anterior para tomar la decisión.grep -w
comprueba patrones de palabras enteras.fuente
También puede usar (* comodines) fuera de una declaración de caso, si usa corchetes dobles:
fuente
*My*
) deben estar en el lado derecho de la prueba.Si su lista de valores debe estar codificada en la secuencia de comandos, es bastante fácil de probar usando
case
. Aquí hay un breve ejemplo, que puede adaptar a sus necesidades:Si la lista es una variable de matriz en tiempo de ejecución, una de las otras respuestas probablemente sea mejor.
fuente
Si la lista está arreglada en el script, me gusta lo siguiente mejor:
Luego, use
validate "$x"
para probar si$x
está permitido.Si desea una línea y no le importa el espacio en blanco en los nombres de los elementos, puede usar esto (aviso en
-w
lugar de-x
):Notas:
sh
con POSIX .validate
no no aceptar subcadenas (quitar la-x
opción de grep si quieres que).validate
interpreta su argumento como una cadena fija, no como una expresión regular (elimine la-F
opción grep si lo desea).Código de muestra para ejercer la función:
fuente
Considere explotar las claves de las matrices asociativas . Supongo que esto supera tanto la coincidencia de expresiones regulares / patrones como el bucle, aunque no lo he perfilado.
Salida:
fuente
echo -n
) con el uso creativo de los parámetros:do is="${list[$value]+is }"; echo "$value ${is:-is *not* }a member of ( ${!list[*]} )"; done
.Creo que es más fácil usar el formulario
echo $LIST | xargs -n1 echo | grep $VALUE
como se ilustra a continuación:Esto funciona para una lista separada por espacios, pero puede adaptarla a cualquier otro delimitador (como
:
) haciendo lo siguiente:Tenga en cuenta que
"
son necesarios para que la prueba funcione.fuente
LIST="SOMEITEM1 ITEM2"
que se vuelva verdadero aunqueITEM1
no esté en élPensé en agregar mi solución a la lista.
fuente
Ejemplos
en lista
fuente
Suponiendo que la variable TARGET puede ser solo 'binomial' o 'regresión', lo siguiente sería suficiente:
Puede agregar más cadenas a la lista separándolas con un | (pipa) personaje.
La ventaja de utilizar egrep es que puede agregar fácilmente mayúsculas y minúsculas (-i) o verificar escenarios más complejos con una expresión regular.
fuente
Esta es casi su propuesta original, pero casi una línea. No es tan complicado como otras respuestas válidas, y no tan dependiendo de las versiones de bash (puede funcionar con bashes antiguos).
Supongo que mi propuesta aún se puede mejorar, tanto en longitud como en estilo.
fuente
Si no es demasiado largo; simplemente puede encadenarlos entre la igualdad a lo largo de una comparación OR lógica como tal.
Tuve este problema exacto y aunque lo anterior es feo, es más obvio lo que está sucediendo que las otras soluciones generalizadas.
fuente