[英]Bash: for in loop with brace expansion in list
我想編寫一個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
有誰知道我該怎么做?
非常感謝你!
我擔心在這種情況下您可能不得不求助於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
。
編輯
盡管有一個eval
的時間和地點,但對於一般情況而言,這並不是最安全的方法。 請參閱為什么在Bash中應避免使用eval,而應該使用什么呢? 由於某些原因。
使用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
或者在TEXT
而不是每個元素上使用eval:
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
沒有eval
,但是有命令替換:
$ text="$(echo a b c d{a..c} e f)"
$ echo "$text"
a b c da db dc e f
而且,正如湯姆的答案中提到的那樣,數組可能是進入此處的更好方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.