
Ich suche nach einem „In“-Operator, der ungefähr so funktioniert:
if [ "$1" in ("cat","dog","mouse") ]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
Es handelt sich dabei offensichtlich um eine viel kürzere Anweisung als beispielsweise bei der Verwendung mehrerer „oder“-Tests.
Antwort1
Sie können verwenden case
...esac
$ cat in.sh
#!/bin/bash
case "$1" in
"cat"|"dog"|"mouse")
echo "dollar 1 is either a cat or a dog or a mouse"
;;
*)
echo "none of the above"
;;
esac
Ex.
$ ./in.sh dog
dollar 1 is either a cat or a dog or a mouse
$ ./in.sh hamster
none of the above
Mit ksh
, bash -O extglob
oder zsh -o kshglob
können Sie auch ein erweitertes Glob-Muster verwenden:
if [[ "$1" = @(cat|dog|mouse) ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
else
echo "none of the above"
fi
Mit bash
, ksh93
oder zsh
können Sie auch einen Vergleich mit regulären Ausdrücken verwenden:
if [[ "$1" =~ ^(cat|dog|mouse)$ ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
else
echo "none of the above"
fi
Antwort2
In Bash gibt es keinen „In“-Test, aber einen Regex-Test (nicht in Bourne):
if [[ $1 =~ ^(cat|dog|mouse)$ ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
Und normalerweise mithilfe einer Variablen geschrieben (weniger Probleme mit Anführungszeichen):
regex='^(cat|dog|mouse)$'
if [[ $1 =~ $regex ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
Für eine ältere Bourne-Shell müssen Sie die Groß-/Kleinschreibung beachten:
case $1 in
cat|dog|mouse) echo "dollar 1 is either a cat or a dog or a mouse";;
esac
Antwort3
Die Verwendung von a case
ist in Ordnung, wenn Sie einen festen Satz von Haustieren haben, mit denen Sie vergleichen möchten. Es funktioniert jedoch nicht, wenn Sie das Muster zur Laufzeit erstellen müssen, da case
es die Abwechslung innerhalb erweiterter Parameter nicht interpretiert.
Dies entspricht nur der wörtlichen Zeichenfolge cat|dog|mouse
:
patt='cat|dog|mouse'
case $1 in
$patt) echo "$1 matches the case" ;;
esac
Sie können jedoch eine Variable mit der regulären Ausdrucksübereinstimmung verwenden. Solange die Variable nicht in Anführungszeichen steht, haben alle darin enthaltenen Regex-Operatoren ihre spezielle Bedeutung.
patt='cat|dog|mouse'
if [[ "$1" =~ ^($patt)$ ]]; then
echo "$1 matches the pattern"
fi
Sie können auch assoziative Arrays verwenden. Die Überprüfung, ob ein Schlüssel in einem Array vorhanden ist, kommt einem in
Operator, den Bash bietet, am nächsten. Allerdings ist die Syntax ein wenig hässlich:
declare -A arr
arr[cat]=1
arr[dog]=1
arr[mouse]=1
if [ "${arr[$1]+x}" ]; then
echo "$1 is in the array"
fi
(${arr[$1]+x}
wird erweitert auf , x
wenn arr[$1]
gesetzt ist, andernfalls leer.)
Antwort4
grep
Ansatz.
if echo $1 | grep -qE "^(cat|dog|mouse)$"; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
-q
um jegliche Ausgabe auf dem Bildschirm zu vermeiden (schneller einzutippen als>/dev/null
).-E
für erweiterte reguläre Ausdrucksaspekte(cat|dog|mouse)
ist dies erforderlich.^(cat|dog|mouse)$
^
passt zu allen Zeilen, die mit Katze, Hund oder Maus ( ) beginnen,(cat|dog|mouse)
gefolgt vom Zeilenende ($
)