GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie verwende ich eine Variable als Fallbedingung?

Ich versuche, eine Variable zu verwenden, die aus verschiedenen Zeichenfolgen besteht, die durch einen | getrennt sind als case Aussagetest. Zum Beispiel:

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

Ich möchte foo eingeben können oder bar und führe den ersten Teil des case aus Erklärung. Allerdings sind beide foo und bar bringt mich zum zweiten:

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

Verwenden von "$string" statt $string macht keinen Unterschied. Auch nicht die Verwendung von string="foo|bar" .

Ich weiß, dass ich es so machen kann:

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

Mir fallen verschiedene Problemumgehungen ein, aber ich würde gerne wissen, ob es möglich ist, eine Variable als case zu verwenden Zustand in bash. Ist das möglich und wenn ja, wie?

Akzeptierte Antwort:

Im Bash-Handbuch heißt es:

case Wort in [ [(] Muster [ | Muster ] … ) Liste;; ] … esac

Jedes untersuchte Muster wird durch Tilde-Erweiterung, Parameter- und Variablen-Erweiterung, arithmetische Substitution, Befehls-Substitution und Prozess-Substitution erweitert.

Keine «Pfadnamenerweiterung»

Also:ein Muster wird NICHT mit «Pathname expansion» erweitert.

Daher:ein Muster darf NICHT „|“ enthalten Innerhalb. Nur:zwei Muster konnten mit dem „|“ verbunden werden.

Das funktioniert:

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

Verwendung von „Extended Globbing“

Allerdings word wird mit pattern abgeglichen unter Verwendung von „Pathname Expansion“-Regeln.
Und „Extended Globbing“ erlaubt hier, hier und hier die Verwendung von alternierenden („|“) Mustern.

Das funktioniert auch:

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

String-Inhalt

Das nächste Testskript zeigt, dass das Muster mit allen Zeilen übereinstimmt, die entweder foo enthalten oder bar irgendwo ist '*$(foo|bar)*' oder die beiden Variablen $s1=*foo* und $s2=*bar*

Testskript:

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. So verwenden Sie BusyBox unter Linux

  2. So verwenden Sie Bash-Verlaufsbefehle

  3. Wie ich Cron unter Linux verwende

  4. So verwenden Sie Nginx zum Umleiten

  5. Wie wird eine indirekte Variablenauswertung durchgeführt?

So verwenden Sie Telnet unter Windows

So verwenden Sie Instagram im Terminal

So verwenden Sie den PS-Befehl

So verwenden Sie den TOP-Befehl

Wie benutzt man das Hud?

So verwenden Sie FTP