2 bash中的维度数组,不能给数组中的某个元素赋值

2 Dimensional array in bash, cannot set value to a certain element in array

我在 bash 中有一个二维数组,我能够成功初始化它,但是当我选择为数组中的某个元素设置一个值时 - 脚本将它设置为所有元素在数组中!莫名其妙!我希望它会设置为只有那个元素。

场景如下 - 我有一个二维数组,用于一年中的所有 12 个月。 (假设是 2012 年。)我可以将其初始化为“-1”。稍后在代码中我只想将第 6 个月设置为 1000,然后 'initializing' 将 1000 设置为数组中的所有元素。为什么 ? 我在 Mac OS Yosemite 10.10.5 和 运行 这是 /bin/bash

declare -a outages

function init_array () {
    for (( month=1; month<12; month++)) do
        outages[$month,12]=-1
    done
    outages[6,12]=1000 # this is setting all elements to 1000, instead of just 1.
}
function print_array () {

    for ((i=1;i<=12;i++)) do
         echo  outages[$i,12] = ${outages[$i,12]}
    done

}
init_array
print_array

Results Cut and Pasted below.
./test.sh 
outages[1,12] = 1000
outages[2,12] = 1000
outages[3,12] = 1000
outages[4,12] = 1000
outages[5,12] = 1000
outages[6,12] = 1000
outages[7,12] = 1000
outages[8,12] = 1000
outages[9,12] = 1000
outages[10,12] = 1000
outages[11,12] = 1000
outages[12,12] = 1000

Bash 有两种类型的数组:one-dimensional 索引数组和关联数组。 declare -a 创建一个 one-dimensional 数组。要模拟二维数组,您需要一个关联数组。因此,替换:

declare -a outages

与:

declare -A outages

有了那个变化:

$ bash test.sh
outages[1,12] = -1
outages[2,12] = -1
outages[3,12] = -1
outages[4,12] = -1
outages[5,12] = -1
outages[6,12] = 1000
outages[7,12] = -1
outages[8,12] = -1
outages[9,12] = -1
outages[10,12] = -1
outages[11,12] = -1
outages[12,12] =

(请注意,永远不会设置 outages[12,12],因为循环受到 month<12 的限制。)

向一维数组提供二维下标时会发生什么

与原始代码一样,让我们​​声明一个一维数组并将其用作二维数组,看看会发生什么:

$ declare -a outages
$ outages[1,2]=-1

看起来它成功地分配了一个二维数组。 但是,事实并非如此。 要查看实际情况,请使用 declare -p:

$ declare -p outages
declare -a outages='([2]="-1")'

我们可以看到元素 2 被分配了一个值,而不是元素 1,2。原因是一维数组的下标被视为算术表达式。根据算术评估规则,anything before a comma is discarded.

直接看一个算术表达式就可以看出这一点:

$ echo $((1,2))
2

, 之前的所有内容都将被丢弃。这就是为什么设置 outages[6,12]=1000 会产生将所有其他 ,12 元素设置为 1000 的效果。

文档

来自 man bash 标题为 "ARITHMETIC EVALUATION" 的部分:

The operators and their precedence, associativity, and values are the same as in the C language.

需要参考 C 语言文档,例如 here,以了解逗号运算符的实际作用。

用bash3.x

模拟二维数组

有一些技巧可以将 2-D-like 特征插入 bash 3.x 的一维数组中。例如,参见 here or here。但是,在这种情况下,您的下标是数字,并且可以采用更简单的方法。让我们像这样更新代码:

$ cat test2.sh
declare -a outages

function init_array () {
    for (( month=1; month<=12; month++)) do
        outages[$month+100*12]=-1
    done
    outages[6+100*12]=1000 # this is setting all elements to 1000, instead of just 1.
}
function print_array () {

    for ((i=1;i<=12;i++)) do
         echo  "outages[$i,12] = ${outages[$i+100*12]}"
    done

}
init_array
print_array

代码运行如你所愿:

$ bash test2.sh
outages[1,12] = -1
outages[2,12] = -1
outages[3,12] = -1
outages[4,12] = -1
outages[5,12] = -1
outages[6,12] = 1000
outages[7,12] = -1
outages[8,12] = -1
outages[9,12] = -1
outages[10,12] = -1
outages[11,12] = -1
outages[12,12] = -1

我们可以看到数组 outages 看起来像 bash 和 declare -p:

$ declare -p outages
declare -a outages='([1201]="-1" [1202]="-1" [1203]="-1" [1204]="-1" [1205]="-1" [1206]="1000" [1207]="-1" [1208]="-1" [1209]="-1" [1210]="-1" [1211]="-1" [1212]="-1")'