2012-11-06 88 views
18

我想寫一個Bash腳本,它在case語句中使用變量作爲模式。但是我無法讓它工作。在變量中使用變量作爲案例模式

案例聲明:

case "$1" in 
    $test) 
     echo "matched" 
     ;; 
    *) 
     echo "didn't match" 
     ;; 
esac 

我已經與分配$testaaa|bbb|ccc(aaa|bbb|ccc)[aaa,bbb,ccc]和其他幾個組合嘗試這個。我也試過這些案例陳述中的模式:@($test)@($(echo $test))$($test)。也沒有成功。

編輯

爲清楚起見,我想的變量來表示這樣的多模式:

case "$1" in 
    aaa|bbb|ccc) 
     echo "matched" 
     ;; 
    *) 
     echo "didn't match" 
     ;; 
esac 

回答

17

可以使用extglob選項:

#! /bin/bash 

shopt -s extglob   # enables pattern lists like +(...|...) 
test='+(aaa|bbb|ccc)' 

for x in aaa bbb ccc ddd ; do 
    echo -n "$x " 
    case "$x" in 
     $test) echo Matches. 
     ;; 
     *) echo Does not match. 
    esac 
done 
+2

+1提醒我使用'extglob'。順便說一句'test ='@(aaa | bbb | ccc)''也可以,在這種情況下可能是更好的選擇。 – anubhava

+0

這太棒了!謝謝! @anubhava爲什麼你的建議會更好(@而不是+)? – siebz0r

+1

@anubhava沒關係,在[這裏]找到它(https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching)。 @匹配一個匹配項,+匹配多個匹配項。 – siebz0r

3

更新):這裏的東西有點不同,但我希望它的工作原理爲您需要它:

#!/bin/bash 

pattern1="aaa bbb ccc" 
pattern2="hello world" 
test=$(echo -e "$pattern1\n$pattern2" | grep -e $1) 

case "$test" in 
    "$pattern1") 
     echo "matched - pattern1" 
     ;; 
    "$pattern2") 
     echo "matched - pattern2" 
     ;; 
    *) 
     echo "didn't match" 
     ;; 
esac 

這使用grep爲您做模式匹配,但仍允許您指定多個模式集以用於case-statement結構中。

例如:

  • 如果任aaabbb,或ccc是第一個參數到腳本,這將輸出matched - pattern1
  • 如果helloworld是第一個參數,則會輸出matched - pattern2
  • 否則它會輸出didn't match
+2

如果$ 1爲AAA,不爲BBB和CCC這可能工作。 – Guru

+0

@Guru是對的。這隻會匹配第一個,因爲'test'變成'aaa'。 – siebz0r

+0

@ siebz0r更新了答案 - 看看這是否適合你。 –

1

使用eval也可以工作:

eval 'case "$1" in 

    '$test') 
     echo "matched" 
     ;; 
    *) 
     echo "did not match" 
     ;; 
esac'