在 Bash 脚本中将数组分配给变量似乎相当复杂:
a=("a" "b" "c")
b=$a
echo ${a[0]}
echo ${a[1]}
echo ${b[0]}
echo ${b[1]}
导致
a
b
a
代替
a
b
a
b
为什么?我该如何解决?
如果要将包含数组的变量复制到另一个名称,请执行以下操作:
a=('a' 'b' 'c')
b=( "${a[@]}" )
如果a
是一个数组,则$a
展开到数组中的第一个元素。这就是为什么b
在您的示例中只有一个值。在 bash 中,引用数组的变量不能像 C++ 或 Java 中的指针那样赋值。相反,变量扩展(如在参数扩展中)为字符串,这些字符串被复制并与被分配的变量相关联。
要复制包含带空格的值的稀疏数组,必须通过索引一次复制一个元素 - 可以使用 ${!a[@]} 获得。
declare -a b=()
for i in ${!a[@]}; do
b[$i]="${a[$i]}"
done
从 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
印刷:
a indicies: 1 3
b indicies: 1 3 # or 0 1 with line uncommented
values in b:
red hat
fedora core
这也适用于 bash 4 中的关联数组,如果您declare -A
在声明数组时使用(使用大写 A 而不是小写)。