[英]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.