是否可以使用 检查变量是否包含在数组中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
并且$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
在函数/源文件中使用)跳过后续