J'essaye d'écrire un script en bash qui vérifie la validité d'une entrée d'utilisateur.
Je veux faire correspondre l'entrée (disons la variable x
) à une liste de valeurs valides.
ce que je suis venu avec pour le moment est:
for item in $list
do
if [ "$x" == "$item" ]; then
echo "In the list"
exit
fi
done
Ma question est de savoir s'il existe un moyen plus simple de le faire,
quelque chose comme list.contains(x)
pour la plupart des langages de programmation.
Ajout:
Dites que la liste est:
list="11 22 33"
mon code ne fera écho au message que pour ces valeurs car il list
est traité comme un tableau et non comme une chaîne, toutes les manipulations de chaîne seront validées 1
alors que je voudrais qu'il échoue.
[[ $list =~ (^| )$x($| ) ]] && echo 'yes' || echo 'no'
x=.
contains () { [[ "$1" =~ (^|[[:space:]])"$2"($|[[:space:]]) ]]; }
.[[ " $list " =~ " $x " ]] && echo 'yes' || echo 'no'
. c'est correct en supposant que l'espace est le séparateur et$x
ne contient pas d'espaceisIn()
afin que vous puissiez d'abord écrire l'élément dans les paramètres. Vous pouvez égalementecho
utiliser quelque chose au lieu d'utiliserexit
comme ceci:[[ $2 =~ (^|[[:space:]])$1($|[[:space:]]) ]] && echo 1 || echo 0
Vous pouvez donc utiliser la fonction de cette façon:result=$(isIn "-t" "-o -t 45") && echo $result
Matvey a raison, mais vous devriez citer $ x et considérer tout type d '"espaces" (par exemple, nouvelle ligne) avec
donc, ie
fin alors
ou
Notez que vous devez utiliser
""
en cas de variables:la source
$item
contient des caractères spéciaux, comme.
(mais la$list
variable doit probablement être citée dans le test). Et la fonction peut être définie encore plus simple:contains () { [[ "$1" =~ (^|[[:space:]])"$2"($|[[:space:]]) ]]; }
.list="aa bb xx cc ff"
etx="aa bb"
$list =~ (^|[[:space:]])"$item"($|[[:space:]])
. Ou, si vous avez le temps, je serais heureux d'entendre votre explication pour cette expression. Remarque: je suppose que c'est une expression regex (commence par ^ etc) mais je ne sais pas ce que signifie = ~. J'adorerais donc une explication générale: PLa solution la plus simple à mon humble avis est de préfixer et d'ajouter la chaîne d'origine avec un espace et de vérifier par rapport à une expression régulière avec
[[ ]]
ce ne sera pas un faux positif sur les valeurs avec des valeurs contenant l'aiguille comme sous-chaîne, par exemple avec une botte de foin
foo barbaz
.(Le concept est volé sans vergogne de la
hasClass()
-Méthode de JQuery )la source
haystack="foo:bar"
et[[ ":$haystack:" = *:$needle:* ]]
que diriez-vous
vous pouvez vérifier la sortie ou la
$?
ligne ci-dessus pour prendre la décision.grep -w
vérifie les modèles de mots entiers.la source
Vous pouvez également utiliser (* wildcards) en dehors d'une instruction case, si vous utilisez des doubles crochets:
la source
*My*
) doivent être sur le côté droit du test.Si votre liste de valeurs doit être codée en dur dans le script, son utilisation est assez simple à tester
case
. Voici un petit exemple que vous pouvez adapter à vos besoins:Si la liste est une variable de tableau au moment de l'exécution, l'une des autres réponses est probablement mieux adaptée.
la source
Si la liste est fixe dans le script, j'aime ce qui suit le plus:
Ensuite, utilisez
validate "$x"
pour tester si cela$x
est autorisé.Si vous voulez un one-liner et que vous ne vous souciez pas des espaces dans les noms d'éléments, vous pouvez utiliser ceci (notez
-w
au lieu de-x
):Remarques:
sh
conforme à POSIX .validate
n'accepte pas les sous-chaînes (supprimez l'-x
option de grep si vous le souhaitez).validate
interprète son argument comme une chaîne fixe, pas comme une expression régulière (supprimez l'-F
option de grep si vous le souhaitez).Exemple de code pour exercer la fonction:
la source
Pensez à exploiter les clés des tableaux associatifs . Je suppose que cela surpasse à la fois la correspondance regex / modèle et la mise en boucle, bien que je ne l'ai pas profilé.
Production:
la source
echo -n
) avec l' utilisation créative des paramètres:do is="${list[$value]+is }"; echo "$value ${is:-is *not* }a member of ( ${!list[*]} )"; done
.Je trouve qu'il est plus facile d'utiliser le formulaire
echo $LIST | xargs -n1 echo | grep $VALUE
comme illustré ci-dessous:Cela fonctionne pour une liste séparée par des espaces, mais vous pouvez l'adapter à n'importe quel autre délimiteur (comme
:
) en procédant comme suit:Notez que les
"
sont nécessaires pour que le test fonctionne.la source
LIST="SOMEITEM1 ITEM2"
revenir vrai même si ceITEM1
n'est pas dedansJe pensais ajouter ma solution à la liste.
la source
Exemples
dans la liste
la source
En supposant que la variable TARGET ne peut être que 'binomiale' ou 'régression', alors ce qui suit ferait:
Vous pouvez ajouter plus de chaînes dans la liste en les séparant par un | (pipe) caractère.
L'avantage d'utiliser egrep est que vous pouvez facilement ajouter une insensibilité à la casse (-i), ou vérifier des scénarios plus complexes avec une expression régulière.
la source
C'est presque votre proposition originale mais presque une 1-ligne. Pas si compliqué que d'autres réponses valides, et pas selon les versions de bash (peut fonctionner avec d'anciennes bashes).
Je suppose que ma proposition peut encore être améliorée, à la fois en longueur et en style.
la source
Si ce n'est pas trop long; vous pouvez simplement les enchaîner entre les égalités le long d'une comparaison OU logique comme ceci.
J'ai eu ce problème exact et bien que ce qui précède soit moche, ce qui se passe est plus évident que les autres solutions généralisées.
la source