Bash

如何使用變數作為案例條件?

  • June 18, 2020

我正在嘗試使用一個由不同字元串組成的變數,用 a 分隔|作為case語句測試。例如:

string="\"foo\"|\"bar\""
read choice
case $choice in
   $string)
       echo "You chose $choice";;
   *)
       echo "Bad choice!";;
esac

我希望能夠鍵入foobar執行case語句的第一部分。但是,兩者都foobar我到第二個:

$ 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

使用“擴展萬用字元”

但是,wordpattern使用«路徑名擴展»規則相匹配。

並且« 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

字元串內容

下一個測試腳本顯示匹配包含其中一個foobar任何位置的所有行的模式是'*$(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_

引用自:https://unix.stackexchange.com/questions/234264