繁体   English   中英

重击:在列表中循环进行大括号扩展

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM