我设法让二维关联数组适用于这个例子:
首先,让我们将这些数据放入一个文件中
$ cat table.txt
KEYS VALS
---- ----
keyp val1
keyp val2
keyp val3
keyp val6
keyc val4
keym val4
keys val8
keyr val8
keyb val5
我们将使用一个名为“table”的关联数组
typeset -A table
现在,让我们填充数组。这里棘手的一点是我们需要声明数组的每个元素本身就是一个关联数组。当我们遇到不在“table”中的键时,我们需要这样做:
i=0
sed '1,2d' table.txt | while read -r key value; do
[[ -z "${table[$key]+not set}" ]] && typeset -A table[$key]
table[$key][$value]=$((++i))
done
现在,让我们看看表格数组中有什么
for key in "${!table[@]}"; do
for subkey in "${!table[$key][@]}"; do
printf "%s\t%s\t%s\n" "$key" "$subkey" "${table[$key][$subkey]}"
done
done
keyb 0
keyb val5 9
keyc 0
keyc val4 5
keym 0
keym val4 6
keyp 0
keyp val1 1
keyp val2 2
keyp val3 3
keyp val6 4
keyr 0
keyr val8 8
keys 0
keys val8 7
一切都很好,除了每个顶级键还有一个子键“0”。这看起来很奇怪,但我认为这就是在 ksh 中实现变量的方式。即使是简单的标量变量也可以引用为索引为 0 的数组:
$ foo=bar
$ echo "$foo"
bar
$ echo "${foo[0]}"
bar
$ printf "%s\n" "${!foo[@]}"
0
问题的核心:检索特定键的值:
parm_key="keyp"
typeset -a values
for val in "${!table[$parm_key][@]}"; do
[[ $val = "0" ]] || values+=("$val")
done
printf "%s\n" "${values[@]}"
val1
val2
val3
val6
我刚刚意识到这太复杂了。我们不需要关联数组的关联数组。我们想要一个索引数组的关联数组:
$ unset table
$ typeset -A table
$ sed '1,2d' table.txt | while read -r key value; do table[$key]+=("$value"); done
$ printf "%s\n" "${!table[@]}"
keyb
keyc
keym
keyp
keyr
keys
$ for key in "${!table[@]}"; do for val in "${table[$key][@]}"; do printf "%s\t%s\n" "$key" "$val"; done; done
keyb val5
keyc val4
keym val4
keyp val1
keyp val2
keyp val3
keyp val6
keyr val8
keys val8
$ printf "%s\n" "${table[$parm_key][@]}"
val1
val2
val3
val6