如何使用另一个字符串参数创建和初始化数组

时间:2016-12-14 02:42:46

标签: arrays shell

context 1:

~ arr=( {1..3} 5 {7..10} )
~ echo ${arr[@]}
1 2 3 5 7 8 9 10

如果我想将细节存储在字符串参数中,如下所示:

context 2:

~ a="{1..3} 5 {7..10}"
~ arr=( "$a" )
~ echo ${arr[@]}
{1..3} 5 {7..10}

有没有一种简单的方法可以用于上下文2来实现上下文1的结果?

1 个答案:

答案 0 :(得分:1)

您可以使用eval,但has inherent security risks,所以您应首先询问是否有更安全的方法来执行此操作。

请注意,我假设bash为shell,因为它支持数组和大括号扩展 - 与the POSIX shell spec.

不同

如果你确实想要使用eval

a="{1..3} 5 {7..10}"
read -ra arr < <(eval echo "{1..3} 5 {7..10}")
echo "${arr[@]}"

以下表单适用于bashkshzsh,但它有陷阱:

a="{1..3} 5 {7..10}"
arr=( $(eval echo "{1..3} 5 {7..10}") )
echo "${arr[@]}"

命令替换($(...))的输出受到分词和通配的影响,这可能会产生意外结果。
随着手头的输入 - 表示整数的字符串 - 这不是问题,但是最好不要习惯使用arr=( $(...) )填充数组

不幸的是,read语法在shell之间有所不同,所以 - 通过额外的工作和关注 - 可以使arr=( $(...) )健壮地工作 (但是如果你知道你只使用一个特定的shell,那通常不值得):

a="{1..3} 5 {7..10}"
# Save the previous $IFS value, set it to the desired separator, and turn off globbing.
oIFS=$IFS; IFS=' '; set -f
arr=( $(eval echo "{1..3} 5 {7..10}") )
# Restore $IFS, turn globbing back on.
IFS=$OFS; set +f
printf '%s\n' "${arr[@]}"