我有很多关联数组,我只想使用 1 个循环。按给定名称选择循环数组
我想用一个变量选择/构建数组名的一部分,然后用那个名字循环,但它不起作用。
与 OUTPUT3 和 OUTPUT4 类似,但语法错误。
对于输出 3,我收到:“bash 错误替换”
对于输出 4,我收到:“只有数组名和 0”
#!/bin/bash
clear
declare -A a1 a2 a3
a1['1']="1-1V"
a2['1']="2-1V"
a2['2']="2-2V"
a3['1']="3-1V"
a3['2']="3-2V"
a3['3']="3-3V"
# 1 OUTPUT WORKS
for i in ${!a1[*]}
do
echo -e "$i : ${a1[$i]}"
done
# 2 OUTPUT WORKS
for i in ${!a2[*]}
do
echo -e "$i : ${a2[$i]}"
done
# 3 OUTPUT - WRONG SYNTAX
selectkey="3"
for i in ${!a$selectkey[@]}
do
echo -e "$i : ${a$selectkey[$i]}"
done
# 4 OUTPUT - WRONG SYNTAX
key="3"
aselect="a${key}[*]"
# THIS ECHO WORKS
echo -e "ARRAY: ${!aselect}"
for i in ${!aselect[@]}
do
echo -e "$i : ${aselect[$i]}"
done
更新
解决方案是nameref
|declare -n
这现在对我有用:
#!/bin/bash
clear
declare -A a1 a2 a3
a1['1']="1-1V"
a2['1']="2-1V"
a2['2']="2-2V"
a3['1']="3-1V"
a3['2']="3-2V"
a3['3']="3-3V"
varname="a3"
counter=1
declare -n refname=${varname}
for i in "${!refname[@]}"
do
echo -e "$counter ${refname[$counter]}"
counter=$((counter+1))
done
使用“nameref”:
declare -n a=b
使 variable 成为 variablea
的别名b
。产出
关联数组本质上是无序的。
对于 #4,您正在使用“间接扩展”,如Shell Parameter Expansion中所述,但您无法使用该技术获取数组的索引。
bash
没有多维数组。但是,您可以使用关联数组和键连接(key1
并key2
表示为组合字符串key1,key2
)来实现它们。这里有些例子。鉴于您的起始场景,
所有
a[1,*]
值:输出
所有
a[*,2]
值:输出
生成密钥集的另一种方法:
输出
请注意,在所有情况下,键都不是按数字顺序排列的。如果这是必需的,您可以修改
printf | awk
构造以通过管道sort -n
(假设数字键)。您还可以概括该
awk
构造,以便您可以指定字段编号以及所需的键值。这将有助于封装,也许通过将密钥生成隐藏在函数中如果您的索引是数字,您最好使用常规数组而不是关联数组。两者都可以是稀疏的,但常规数组让您可以按数字顺序迭代键,而对于关联数组,它本质上是随机的。(在其他语言中,您可能需要关联数组来获得稀疏数组。)比较:
再一次,如果你的索引是数字并且数组不是稀疏的,你可以使用关联数组来伪造一个二维数组,并用手动循环迭代索引。
(当然,您可以通过将“不存在的”元素设置为某个特殊值来模拟稀疏数组,然后在循环中忽略这些值。)
Ksh 实际上还支持二维数组,或者至少支持嵌套列表:
虽然这不起作用:
但是,需要复杂的数据结构也是考虑从 shell 切换到其他一些编程语言可能有用的情况之一。
在任何情况下,都不要使用
${!array[*]}
, 或${!array[@]}
(有或没有!
),而是"${!array[@]}"
因为这是唯一保持包含空白的值完整的方法。尝试 egz=("foo bar" "zoom")
,然后使用orfor x in ${z[*]}; do echo $x; done
与相同的进行比较。"${z[*]}"
"${z[@]}"