2016-03-01 37 views
1

我想寫一個for循環,其中可能的值取自另一個變量。我無法弄清楚的部分是如何包含需要擴展的值。例如:Bash:for循環與列表中的大括號擴展

TEXT="a b c d{a..c} e f" 
for VAR in $TEXT; do echo $VAR; done 

我得到的是

a 
b 
c 
d{a..c} 
e 
f 

但我要的是

a 
b 
c 
da 
db 
dc 
e 
f 

有誰知道我能得到這個工作?

非常感謝!

回答

4

我怕你可能不得不求助於在這種情況下使用eval ......不過,我建議你迴避使用一個循環:

eval "printf '%s\n' $TEXT" 

使用eval意味着括號將擴大,產生你想要的結果。

你可以看看會發生什麼用set -x

$ set -x 
$ eval "printf '%s\n' $TEXT" 
+ eval 'printf '\''%s\n'\'' a b c d{a..c} e f' 
++ printf '%s\n' a b c da db dc e f 
a 
b 
c 
da 
db 
dc 
e 
f 

注意,之前的列表作爲參數傳遞給printf出現擴張。

如果你定義$TEXT自己,要遍歷它的每一個展開的元件的,我建議使用數組來代替:

text=(a b c d{a..c} e f) 
for var in "${text[@]}"; do 
    # whatever with "$var" 
done 

這是首選的解決方案,因爲它不涉及使用eval

+1

數組解決方案完美工作。非常感謝你! – noes

+0

同意,數組是這裏要走的路([爲什麼eval對好奇有問題的一些原因](http://stackoverflow.com/q/17529220/3149036)) – tavnab

2

編輯

雖然有一個時間&地方eval,它不是一般的情況下,最安全的方法。出於某些原因,請參閱Why should eval be avoided in Bash, and what should I use instead?


使用eval

TEXT="a b c d{a..c} e f" 
for VAR in $TEXT; do eval echo $VAR; done 

輸出:

a 
b 
c 
da db dc 
e 
f 

如果你想遍歷每個元素,你必須巢您的循環:

for VAR in $TEXT; do 
    for VAR2 in $(eval echo $VAR); do 
    echo $VAR2 
    done 
done 

輸出:

a 
b 
c 
da 
db 
dc 
e 
f 

或者使用eval上TEXT,而不是每個元素:

TEXT="$(eval echo "a b c d{a..c} e f")" 
for VAR in $TEXT; do echo $VAR; done 

輸出:

a 
b 
c 
da 
db 
dc 
e 
f 
+1

謝謝你的幫助! – noes

0

沒有eval,但命令替換:

$ text="$(echo a b c d{a..c} e f)" 
$ echo "$text" 
a b c da db dc e f 

而且如上所述在湯姆的回答中,編輯數組可能是更好的方法。