変数が配列に含まれていることを確認することは可能ですかcase
?次のようなことをしたい
ARR=( opt1 opt2 opt3 );
case $1 in
$ARR)
echo "Option is contained in the array";
*)
echo "Option is not contained in the array";
esac
答え1
そしてksh93
ありがとうこのエラー、あなたはできます:
IFS='|'
ARR=( opt1 opt2 opt3 )
IFS='|'
case $1 in
(@("${ARR[*]}"))
echo "Option is contained in the array";;
(*)
echo "Option is not contained in the array";;
esac
(今後はバグが修正される可能性があるため、これには依存しません。)
これにより、zsh
次のことができます。
case ${ARR[(Ie)$1]}
(0)
echo "Option is not contained in the array";;
(*)
echo "Option is contained in the array";;
esac
(if (( $ARR[(Ie)$1] )); then echo is present...
しかし、ここではケース構成の代わりに使用する方が良いかもしれません)。
${array[(I)pattern]}
パターンに一致する配列の最後の要素インデックスを返し、そうでない場合は0を返します。このe
フラグは精密一致(関連模様マッチ)。
bash
、、、、ksh
のyash
場合などの特定の文字をzsh
想定する準備ができていて、$ARR
その文字がnullでない場合は、次のことができます。$1
@
$ARR
IFS=@
case "@${ARR[*]}@" in
(*"@$1@"*)
echo "Option is contained in the array";;
(*)
echo "Option is not contained in the array";;
esac
を使用すると、bash -O extglob
配列zsh -o kshglob -o globsubst
要素に基づいてパターンを作成するヘルパーを定義できます。
arraypat() {
awk '
BEGIN{
if (ARGC <= 1) print "!(*)"
else {
for (i = 1; i < ARGC; i++) {
gsub(/[][|<>\\?*()]/, "[&]", ARGV[i])
s = s sep ARGV[i]
sep = "|"
}
print "@(" s ")"
}
}' "$@"
}
case $1 in
($(arraypat "${ARR[@]}"))
echo "Option is contained in the array";;
(*)
echo "Option is not contained in the array";;
esac
答え2
実際には小さくて使いやすい方法ではありません。あなたの例では、$ARR
配列の最初の要素にのみ拡張されることを覚えておいてください。opt1
を使用できますが、"${ARR[@]}"
データを使用すると文字列に誤った肯定が表示されることがあります1 opt
。
最新バージョンでは、bash
連想配列の使用を検討できます。
declare -A arr
arr=( [opt1]=1 [opt2]=1 [opt3]=1 )
if [[ "${arr[$1]}" -eq 1 ]]; then
# $1 is a key in arr
else
# is not
fi
答え3
なぜこれを行うのですcase
か?要素ごとの一致ではなく、文字列パターンの一致に使用されます。
正直に言うと、テストを頻繁に「含める」必要があり、テストを短縮したい場合は、見苦しい解決策を使用するのではなく、難しい部分を関数に入れるだけです。
#!/bin/bash
ARR=( foo bar doo );
contains() {
typeset _x;
typeset -n _A="$1"
for _x in "${_A[@]}" ; do
[ "$_x" = "$2" ] && return 0
done
return 1
}
if contains ARR "$1" ; then
echo "\"$1\" is contained in ARR"
else
echo "\"$1\" not contained in ARR"
fi
(これも適用されるべきですksh
)
答え4
ユーザーにはbash
段落ではなく演算子があります;;&
。節では配列を直接サポートしていませんが、case
非常にエレガントです。
ARR=( opt1 opt2 opt3 );
case $1 in
*)
[[ ${ARR[*]} =~ $1 ]] \
&& echo "Option is contained in the array" \
&& exit 0
;;&
*)
echo "Option is not contained in the array"
;;
esac
注;;&
(つまり、非短絡)は、$1
後続のケースセクションの評価を保証しますexit 0
(return 0
関数/ソースファイルで使用されます)。