bash/bourne には「in」演算子がありますか?

bash/bourne には「in」演算子がありますか?

次のような動作をする「in」演算子を探しています。

if [ "$1" in ("cat","dog","mouse") ]; then
    echo "dollar 1 is either a cat or a dog or a mouse"
fi

これは、たとえば複数の「または」テストを使用する場合と比べて、明らかにはるかに短いステートメントです。

答え1

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

kshbash -O extglobまたは を使用する場合はzsh -o kshglob、拡張 glob パターンを使用することもできます。

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

答え2

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 シェルの場合は、大文字と小文字の一致を使用する必要があります。

case $1 in
    cat|dog|mouse)   echo "dollar 1 is either a cat or a dog or a mouse";;
esac

答え3

一致させたいペットのセットが固定されている場合は、 を使用する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

${arr[$1]+x}x設定されている場合は に展開されarr[$1]、それ以外の場合は空になります。

答え4

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)行末()が続く行($)に一致します。

関連情報