间接返回数组中的所有元素

Eri*_*ith 10 bash array

Bash 手册页描述了使用${!a}返回名称为a(间接级别)内容的变量的内容。

我想知道如何使用这个返回数组中的所有元素,即,

a=(one two three)
echo ${a[*]}
Run Code Online (Sandbox Code Playgroud)

返回

one two three
Run Code Online (Sandbox Code Playgroud)

我想要:

b=a
echo ${!b[*]}
Run Code Online (Sandbox Code Playgroud)

返回相同。不幸的是,它没有,而是返回0

更新

鉴于回复,我现在意识到我的例子太简单了,因为当然,像:

b=("${a[@]}")
Run Code Online (Sandbox Code Playgroud)

将完全实现我所说的我需要的。

所以,这就是我想要做的:

LIST_lys=(lys1 lys2)
LIST_diaspar=(diaspar1 diaspar2)

whichone=$1   # 'lys' or 'diaspar'

_LIST=LIST_$whichone
LIST=${!_LIST[*]}
Run Code Online (Sandbox Code Playgroud)

当然,仔细阅读 Bash 手册页表明这不会按预期工作,因为最后一行只是返回“数组”的索引$_LIST(根本不是数组)。

在任何情况下,以下应该做的工作(如所指出的):

LIST=($(eval echo \${$_LIST[*]}))
Run Code Online (Sandbox Code Playgroud)

或者......(我最终走的路线):

LIST_lys="lys1 lys2"
...
LIST=(${!_LIST})
Run Code Online (Sandbox Code Playgroud)

当然,假设元素不包含空格。

Gil*_*il' 8

您需要显式复制元素。对于索引数组:

b=("${a[@]}")
Run Code Online (Sandbox Code Playgroud)

对于关联数组(请注意,这a是数组变量的名称,而不是其值为数组变量名称的变量):

typeset -A b
for k in "${!a[@]}"; do b[$k]=${a[$k]}; done
Run Code Online (Sandbox Code Playgroud)

如果数组中有变量名,则可以使用逐个元素的方法和额外的步骤来检索键。

eval "keys=(\"\${!$name[@]}\")"
for k in "${keys[@]}"; do eval "b[\$k]=\${$name[\$k]}"; done
Run Code Online (Sandbox Code Playgroud)

(警告,这篇文章中的代码是直接在浏览器中输入的,未经测试。)


wey*_*amz 7

我认为使用 bash 变量的间接引用应该按字面处理。

例如。对于您的原始示例:

a=(one two three)
echo ${a[*]} # one two three
b=a
echo ${!b[*]} # this would not work, because this notation 
              # gives the indices of the variable b which
              # is a string in this case and could be thought
              # as a array that conatins only one element, so
              # we get 0 which means the first element
c='a[*]'
echo ${!c} # this will do exactly what you want in the first
           # place
Run Code Online (Sandbox Code Playgroud)

对于最后一个真实场景,我相信下面的代码可以完成工作。

LIST_lys=(lys1 lys2)
LIST_diaspar=(diaspar1 diaspar2)

whichone=$1   # 'lys' or 'diaspar'

_LIST="LIST_$whichone"[*]
LIST=( "${!_LIST}" ) # Of course for indexed array only 
                     # and not a sparse one
Run Code Online (Sandbox Code Playgroud)

最好使用"${var[@]}"可以避免混淆$IFS和 参数扩展的符号。这是最终的代码。

LIST_lys=(lys1 lys2)
LIST_diaspar=(diaspar1 diaspar2)

whichone=$1   # 'lys' or 'diaspar'

_LIST="LIST_$whichone"[@]
LIST=( "${!_LIST}" ) # Of course for indexed array only 
                     # and not a sparse one
                     # It is essential to have ${!_LIST} quoted
Run Code Online (Sandbox Code Playgroud)