GNU/Linux >> Tutoriels Linux >  >> Linux

Comment utiliser une variable comme condition de cas ?

J'essaie d'utiliser une variable composée de différentes chaînes séparées par un | comme un case essai de déclaration. Par exemple :

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

Je veux pouvoir taper foo ou bar et exécutez la première partie du case déclaration. Cependant, les deux foo et bar emmenez-moi à la seconde :

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

Utilisation de "$string" au lieu de $string ça ne fait aucune différence. Utiliser string="foo|bar" non plus .

Je sais que je peux le faire de cette façon :

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

Je peux penser à différentes solutions de contournement, mais j'aimerais savoir s'il est possible d'utiliser une variable comme case condition en bash. Est-ce possible et si oui, comment ?

Réponse acceptée :

Le manuel bash indique :

mot cas dans [ [(] motif [ | motif ] … ) liste;; ] … esac

Chaque modèle examiné est développé à l'aide d'un développement de tilde, d'un développement de paramètres et de variables, d'une substitution arithmétique, d'une substitution de commande et d'une substitution de processus.

Pas de "développement du nom de chemin"

Ainsi :un motif n'est PAS développé avec «Développement du chemin».

Par conséquent :un modèle ne peut PAS contenir "|" à l'intérieur. Uniquement :deux modèles peuvent être joints avec le "|".

Cela fonctionne :

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

Utilisation du « Globbing étendu »

Cependant, word correspond au pattern en utilisant les règles de « Pathname Expansion ».
Et le « Extended Globbing » ici, ici et ici permet l'utilisation de modèles alternés ("|").

Cela fonctionne aussi :

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

Contenu de la chaîne

Le script de test suivant montre que le modèle qui correspond à toutes les lignes contenant soit foo ou bar n'importe où est '*$(foo|bar)*' ou les deux variables $s1=*foo* et $s2=*bar*

Scénario de test :

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. Comment utiliser Nginx pour rediriger

  2. Comment utiliser la commande Su sous Linux

  3. Comment faire une évaluation variable indirecte ?

  4. Comment utiliser dos2unix ?

  5. Dans Puppet, comment puis-je sécuriser une variable de mot de passe (dans ce cas, un mot de passe MySQL) ?

Comment utiliser Telnet sous Windows

Comment utiliser Instagram dans le terminal

Comment utiliser la commande PS

Comment utiliser la commande TOP

Comment utiliser le Hud ?

Comment utiliser FTP