Bash
如何使用變數作為案例條件?
我正在嘗試使用一個由不同字元串組成的變數,用 a 分隔
|
作為case
語句測試。例如:string="\"foo\"|\"bar\"" read choice case $choice in $string) echo "You chose $choice";; *) echo "Bad choice!";; esac
我希望能夠鍵入
foo
或bar
執行case
語句的第一部分。但是,兩者都foo
帶bar
我到第二個:$ foo.sh foo Bad choice! $ foo.sh bar Bad choice!
使用
"$string"
而不是$string
沒有區別。也不使用string="foo|bar"
.我知道我可以這樣做:
case $choice in "foo"|"bar") echo "You chose $choice";; *) echo "Bad choice!";; esac
我可以想到各種解決方法,但我想知道是否可以
case
在 bash 中使用變數作為條件。有可能嗎?如果有,怎麼做?
bash手冊指出:
案例詞在
$$ [( $$圖案$$ | pattern $$… ) 列表 ;; ] … 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
使用“擴展萬用字元”
但是,
word
與pattern
使用«路徑名擴展»規則相匹配。並且« Extended Globbing » here , here和, here允許使用交替 ("|") 模式。
這也有效:
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_