bash手册指出:
[[(]模式[|模式] ...)列表中的大小写单词;] ... esac
使用波浪号扩展,参数和变量扩展,算术替换,命令替换和进程替换来扩展每个检查的模式。
没有“路径名扩展”
因此:模式不能通过“路径扩展”来扩展。
因此:模式不能包含“ |” 内。仅:两个模式可以与“ |”连接。
这有效:
s1="foo"; s2="bar" # or even s1="*foo*"; s2="*bar*"
read choice
case $choice in
$s1|$s2 ) echo "Two val choice $choice"; ;; # not "$s1"|"$s2"
* ) echo "A Bad choice! $choice"; ;;
esac
使用«扩展globbing»
但是,word
与pattern
使用“路径名扩展”规则匹配。此处,此处和此处的
“扩展globbing” 允许使用交替的(“ |”)模式。
这也可以:
shopt -s extglob
string='@(foo|bar)'
read choice
case $choice in
$string ) printf 'String choice %-20s' "$choice"; ;;&
$s1|$s2 ) printf 'Two val choice %-20s' "$choice"; ;;
*) printf 'A Bad choice! %-20s' "$choice"; ;;
esac
echo
字符串内容
下一个测试脚本显示匹配所有包含foo
或bar
任意位置的行的模式是'*$(foo|bar)*'
两个变量$s1=*foo*
,或者$s2=*bar*
测试脚本:
shopt -s extglob # comment out this line to test unset extglob.
shopt -p extglob
s1="*foo*"; s2="*bar*"
string="*foo*"
string="*foo*|*bar*"
string='@(*foo*|*bar)'
string='*@(foo|bar)*'
printf "%s\n" "$string"
while IFS= read -r choice; do
case $choice in
"$s1"|"$s2" ) printf 'A first choice %-20s' "$choice"; ;;&
$string ) printf 'String choice %-20s' "$choice"; ;;&
$s1|$s2 ) printf 'Two val choice %-20s' "$choice"; ;;
*) printf 'A Bad choice! %-20s' "$choice"; ;;
esac
echo
done <<-\_several_strings_
f
b
foo
bar
*foo*
*foo*|*bar*
\"foo\"
"foo"
afooline
onebarvalue
now foo with spaces
_several_strings_
eval
,转义的$ choice,括号,星号,分号和换行符中。丑陋,但“有效”。