次のように機能する「in」演算子を探しています。
if [ "$1" in ("cat","dog","mouse") ]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
これは、たとえば、いくつかの「または」テストを使用する場合と比較して、明らかに短いステートメントです。
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
例.
$ ./in.sh dog
dollar 1 is either a cat or a dog or a mouse
$ ./in.sh hamster
none of the above
ksh
、bash -O extglob
またはzsh -o kshglob
、拡張グロブパターンを使用することもできます。
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
bash
、ksh93
またはzsh
、正規表現の比較を使用することもできます。
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
Bashには「in」テストはありませんが、正規表現テスト(bourneにはありません)があります。
if [[ $1 =~ ^(cat|dog|mouse)$ ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
そして通常、変数を使用して記述されます(引用の問題が少ない):
regex='^(cat|dog|mouse)$'
if [[ $1 =~ $regex ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
古いBourne Shellの場合は、大文字と小文字を一致させる必要があります。
case $1 in
cat|dog|mouse) echo "dollar 1 is either a cat or a dog or a mouse";;
esac
case
を使用しても問題ありません。マッチするペットのセットが決まっている場合は問題ありません。ただし、ランタイムでパターンを構築する必要がある場合は機能しません。case
は拡張パラメーター内からの代替を解釈しないためです。
これはリテラル文字列cat|dog|mouse
のみに一致します:
patt='cat|dog|mouse'
case $1 in
$patt) echo "$1 matches the case" ;;
esac
ただし、正規表現一致で変数を使用できます。変数が引用されていない限り、その中の正規表現演算子には特別な意味があります。
patt='cat|dog|mouse'
if [[ "$1" =~ ^($patt)$ ]]; then
echo "$1 matches the pattern"
fi
連想配列を使用することもできます。キーが存在するかどうかを確認することは、Bashが提供するin
演算子に最も近いものです。構文は少し醜いですが:
declare -A arr
arr[cat]=1
arr[dog]=1
arr[mouse]=1
if [ "${arr[$1]+x}" ]; then
echo "$1 is in the array"
fi
あなたはcouldcase
テストでif
ステートメントを使用しますが、コードは少し複雑になります:
if case "$1" in (cat|dog|mouse) true ;; (*) false; esac; then
printf '"%s" is one of cat, dog or mouse\n' "$1"
else
printf '"%s" is unknown\n' "$1"
fi
または少し短く、
if ! case "$1" in (cat|dog|mouse) false; esac; then
printf '"%s" is one of cat, dog or mouse\n' "$1"
else
printf '"%s" is unknown\n' "$1"
fi
これは、case
句のパターンマッチングを行うためだけにif
句を使用しています。それは不必要な真/偽テストを導入します。
case
を使用することをお勧めします:
case "$1" in
cat|dog|mouse)
printf '"%s" is one of cat, dog or mouse\n' "$1"
;;
*)
printf '"%s" is unknown\n' "$1"
esac
これを行わないでください:
is_one_of () {
eval "case $1 in ($2) return 0; esac"
return 1
}
if is_one_of "$1" 'cat|dog|mouse'; then
printf '"%s" is one of cat, dog or mouse\n' "$1"
else
printf '"%s" is unknown\n' "$1"
fi
またはこれ:
is_one_of () (
Word=$1
shift
IFS='|'
eval "case $Word in ($*) return 0; esac"
return 1
)
if is_one_of "$1" cat dog mouse; then
printf '"%s" is one of cat, dog or mouse\n' "$1"
else
printf '"%s" is unknown\n' "$1"
fi
...危険な残骸を追加しているだけなので、完全に妥当なif
ステートメントの代わりにcase
ステートメントをコードで使用できるようにするためです。
grep
アプローチ。
_if echo $1 | grep -qE "^(cat|dog|mouse)$"; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
_
-q
_を使用すると、画面への出力が回避されます(_>/dev/null
_よりも入力が速くなります)。-E
_拡張正規表現の場合_(cat|dog|mouse)
_アスペクトにはこれが必要です。^(cat|dog|mouse)$
は、(_^
_)で始まり、猫、犬、またはマウス(_(cat|dog|mouse)
_)で始まり、その後に行末が続くすべての行に一致します(_$
_)