206 votes

Vérifier si une variable existe dans une liste en Bash

J'essaie d'écrire un script en bash qui vérifie la validité d'une entrée utilisateur.
Je veux faire correspondre l'entrée (disons la variable x ) à une liste de valeurs valides.

Ce que j'ai trouvé pour l'instant, c'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 procéder,
quelque chose comme un list.contains(x) pour la plupart des langages de programmation.

Dites la liste :

list="11 22 33"

mon code n'affichera le message que pour ces valeurs puisque list est traité comme un tableau et non comme une chaîne de caractères, toutes les manipulations de chaînes de caractères seront validées 1 alors que je voudrais qu'il échoue.

19voto

Kelly Trinh Points 83

S'il n'est pas trop long, vous pouvez simplement l'enchaîner entre l'égalité et une comparaison logique OU, comme suit.

if [ $ITEM == "item1" -o $ITEM == "item2" -o $ITEM == "item3" ]; then
    echo In the list
fi 

J'ai eu exactement le même problème et bien que la solution ci-dessus soit laide, elle est plus évidente que les autres solutions générales.

17voto

Toby Speight Points 3930

Si votre liste de valeurs doit être codée en dur dans le script, il est assez simple de tester en utilisant case . Voici un petit exemple que vous pouvez adapter à vos besoins :

for item in $list
do
    case "$x" in
      item1|item2)
        echo "In the list"
        ;;
      not_an_item)
        echo "Error" >&2
        exit 1
        ;;
    esac
done

Si la liste est un tableau variable au moment de l'exécution, l'une des autres réponses est probablement plus appropriée.

14voto

Amir.n3t Points 232

Il existe un moyen plus propre de vérifier si la chaîne se trouve dans la liste :

if [[ $my_str = @(str1|str2|str3) ]]; then
    echo "string found"
fi

10voto

RubyTuesdayDONO Points 492

Envisagez d'exploiter les clés de tableaux associatifs . Je suppose que cette méthode est plus performante que la recherche de motifs et le bouclage, bien que je ne l'aie pas testée.

declare -A list=( [one]=1 [two]=two [three]='any non-empty value' )
for value in one two three four
do
    echo -n "$value is "
    # a missing key expands to the null string, 
    # and we've set each interesting key to a non-empty value
    [[ -z "${list[$value]}" ]] && echo -n '*not* '
    echo "a member of ( ${!list[*]} )"
done

Sortie :

one is a member of ( one two three )
two is a member of ( one two three )
three is a member of ( one two three )
four is *not* a member of ( one two three )

10voto

Søren Løvborg Points 3425

Si la liste est fixée dans le script, je préfère l'option suivante :

validate() {
    grep -F -q -x "$1" <<EOF
item 1
item 2
item 3
EOF
}

Ensuite, utilisez validate "$x" pour vérifier si $x est autorisée.

Si vous voulez une seule ligne, et que vous ne vous souciez pas des espaces dans les noms d'éléments, vous pouvez utiliser ceci (remarque -w au lieu de -x ) :

validate() { echo "11 22 33" | grep -F -q -w "$1"; }

Notes :

  • C'est POSIX sh conforme.
  • validate fait no acceptent les sous-chaînes (supprimez l'élément -x à grep si vous le souhaitez).
  • validate interprète son argument comme une chaîne de caractères fixe, et non comme un (supprimer l'expression -F à grep si vous le souhaitez).

Exemple de code pour exercer la fonction :

for x in "item 1" "item2" "item 3" "3" "*"; do
    echo -n "'$x' is "
    validate "$x" && echo "valid" || echo "invalid"
done

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X