【发布时间】:2023-03-25 07:40:02
【问题描述】:
在 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
为什么?我该如何解决?
【问题讨论】:
在 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[1]=x; a[3]=y; a[5]=z; b=("${a[@]}"); declare -p a b 给出 declare -A a='([1]="x" [3]="y" [5]="z" )'; declare -a b='([0]="x" [1]="y" [2]="z")' 和 a=([a]=x [b]=y [c]=z); b=("${a[@]}"); declare -p a b 给出 declare -A a='([a]="x" [b]="y" [c]="z" )'; declare -a b='([0]="x" [1]="y" [2]="z")'( ; 添加以提高可读性)
"${a[@]}" 扩展为一个单词列表(每个数组成员一个单词),将该列表包含在( ) 中,形成一个可用于赋值的合适 RHS,b=... 最终执行赋值。我看不出a 在此期间如何丢失其内容,这就是术语 reassign 所暗示的。我错过了什么吗?
a,只是想知道如何将 所有 值从 a 获取到 b。
如果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 而不是小写)。
【讨论】:
b=( "${a[@]}" ) 复制带有空格的元素。见Special Parameters