GNU/Linux >> Linux Esercitazione >  >> Linux

Come utilizzare una variabile come condizione del caso?

Sto cercando di utilizzare una variabile composta da stringhe diverse separate da un | come case prova di affermazione. Ad esempio:

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

Voglio poter digitare foo o bar ed eseguire la prima parte del case dichiarazione. Tuttavia, entrambi foo e bar portami al secondo:

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

Usando "$string" invece di $string non fa differenza. Neanche l'uso di string="foo|bar" .

So che posso farlo in questo modo:

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

Mi vengono in mente varie soluzioni alternative, ma vorrei sapere se è possibile utilizzare una variabile come case condizione in bash. È possibile e, se sì, come?

Risposta accettata:

Il manuale di bash afferma:

parola maiuscola nell'elenco [[(] modello [ | modello ] … );; ] … esac

Ciascun modello esaminato viene espanso utilizzando l'espansione della tilde, l'espansione di parametri e variabili, la sostituzione aritmetica, la sostituzione di comandi e la sostituzione di processi.

Nessuna «Espansione del percorso»

Pertanto:un modello NON viene espanso con «Espansione del nome del percorso».

Pertanto:un pattern NON può contenere “|” dentro. Solo:due pattern possono essere uniti con “|”.

Funziona:

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

Utilizzo di «Globbing esteso»

Tuttavia, word è abbinato a pattern usando le regole di «Espansione del nome».
E «Globbing esteso» qui, qui e qui consente l'uso di pattern alternati ("|").

Funziona anche questo:

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

Contenuto della stringa

Lo script di test successivo mostra che il modello corrisponde a tutte le righe che contengono foo o bar ovunque è '*$(foo|bar)*' oppure le due variabili $s1=*foo* e $s2=*bar*

Script di prova:

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. Come usare BusyBox su Linux

  2. Come usare i comandi della cronologia di Bash

  3. Come uso cron in Linux

  4. Come usare TROVA in Linux

  5. Come utilizzare Nginx per reindirizzare

Come utilizzare Telnet su Windows

Come utilizzare Instagram nel terminale

Come usare il comando PS

Come usare il comando TOP

Come usare l'Hud?

Come utilizzare FTP