将Array分配给变量

use*_*962 31 bash

关于在bash脚本中为变量分配数组的问题看起来相当复杂:

a=("a" "b" "c")
b=$a

echo ${a[0]} 
echo ${a[1]}

echo ${b[0]} 
echo ${b[1]} 
Run Code Online (Sandbox Code Playgroud)

导致

a 
b 
a
Run Code Online (Sandbox Code Playgroud)

代替

a
b
a
b
Run Code Online (Sandbox Code Playgroud)

为什么?我该如何解决?

koj*_*iro 51

如果要将包含数组的变量重新分配给另一个名称,则执行以下操作:

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

  • **注意副作用**:这会重新编号数组/关联数组的键,请参阅:`a =(); a [1] = x; a [3] = y; a [5] = z; b =(“ $ {a [@]}”); define -pab`给出`declare -A a ='([[1] =“ x” [3] =“ y” [5] =“ z”)'; 声明-ab ='([0] =“ x” [1] =“ y” [2] =“ z”)'`和`a =([a] = x [b] = y [c] = z ); b =(“ $ {a [@]}”); 声明-pab`给出`声明-A a ='([[a] =“ x” [b] =“ y” [c] =“ z”)'; 声明-ab ='([[0] =“ x” [1] =“ y” [2] =“ z”)'`(`;`为提高可读性而添加) (4认同)

Cha*_*ers 19

为什么?

如果a是数组,则$a展开到数组中的第一个元素.这就是为什么b在您的示例中只有一个值.在bash中,引用数组的变量不能像指针那样分配在C++或Java中.相反,变量会扩展(如在参数扩展中)为字符串,并且这些字符串将被复制并与所分配的变量相关联.

我该如何解决?

要复制包含带空格值的稀疏数组,必须通过索引一次复制一个元素 - 可以使用$ {!a [@]}获取.

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

从bash手册页:

可以获得数组的键(索引)以及值.$ {!name [@]}和$ {!name [*]}扩展为在数组变量名中指定的索引.双引号中的处理类似于双引号内的特殊参数@和*的扩展.

这是一个你可以自己测试的脚本:

#!/bin/bash

declare -a a=();
a[1]='red hat'
a[3]='fedora core'

declare -a b=();

# Copy method that works for sparse arrays with spaces in the values.
for i in ${!a[@]}; do
    b[$i]="${a[$i]}"
done

# does not work, but as LeVar Burton says ...
#b=("${a[@]}")

echo a indicies: ${!a[@]}
echo b indicies: ${!b[@]}

echo "values in b:"
for u in "${b[@]}"; do
    echo $u
done
Run Code Online (Sandbox Code Playgroud)

打印:

a indicies: 1 3
b indicies: 1 3  # or 0 1 with line uncommented
values in b:
red hat
fedora core
Run Code Online (Sandbox Code Playgroud)

如果declare -A在声明数组时使用(使用大写A而不是小写),这也适用于bash 4中的关联数组.