尝试编写一些嵌套循环,但我不知道如何编写它。也许我看错了方向,但我想写的是:
declare -a bar=("alpha" "bravo" "charlie")
declare -a foo=("delta" "echo" "foxtrot" "golf")
declare -a subgroups=("bar" "foo")
那么我想迭代子组(将来更多酒吧沙富s 将会出现),并在它们内部迭代它们,因为它们可以具有不同数量的元素。
所需的输出类似于:
group name: bar with group members: alpha bravo charlie
working on alpha of the bar group
working on bravo of the bar group
working on charlie of the bar group
group name: foo with group members: delta echo foxtrot golf
working on delta of the foo group
working on echo of the foo group
working on foxtrot of the foo group
working on golf of the foo group
我写的关闭代码似乎失败了酒吧和富数组及其与每个集合上的元素的扩展。
for group in "${subgroups[@]}"; do
lst=${!group}
echo "group name: ${group} with group members: ${!lst[@]}"
for element in "${!lst[@]}"; do
echo -en "\tworking on $element of the $group group\n"
done
done
输出是:
group name: bar with group members: 0
working on 0 of the bar group
group name: foo with group members: 0
working on 0 of the foo group
答案1
这是一个非常常见的问题bash
,在数组中引用数组,您需要使用 来创建名称引用declare -n
。后面的名称 -n
将充当分配的值的名称引用(在 之后=
)。现在我们用 nameref 属性来处理这个变量,就像它是一个数组一样进行扩展,并像以前一样进行完整的正确引用数组扩展。
for group in "${subgroups[@]}"; do
declare -n lst="$group"
echo "group name: ${group} with group members: ${lst[@]}"
for element in "${lst[@]}"; do
echo -en "\tworking on $element of the $group group\n"
done
done
请注意,bash
仅从 v4.3 开始支持 nameref。对于旧版本和其他解决方法,请参阅分配间接/引用变量
答案2
使您的脚本正常工作的最小更改将变为:
#!/bin/bash
declare -a bar=("alpha" "bravo" "charlie")
declare -a foo=("delta" "echo" "foxtrot" "golf")
declare -a groups=("bar" "foo")
for group in "${groups[@]}"; do
lst="$group[@]"
echo "group name: ${group} with group members: ${!lst}"
for element in "${!lst}"; do
echo -en "\tworking on $element of the $group group\n"
done
done
两个主要变化是:
不要使用
"${!lst[@]}"
,甚至不要"${!group[@]}"
访问数组元素。这个语法是仅有的访问数组索引。请使用
${!lst}"
.变量 lst 应设置为包含细绳您应该在正常的里面写入
${ }
,即:lst=foo[@]
在第一级,lst="$group[@]"
如果您需要,数组的名称也是通过变量的值间接的group
。lst="$group[@]"
等效语法 withnamerefs
没有!
(也不需要)扩展值。
因此,需要[@]
将其删除。
echo "using namerefs"
for group in "${groups[@]}"; do
declare -n lst=$group
echo "group name: ${group} with group members: ${lst[@]}"
for element in "${lst[@]}"; do
echo -en "\tworking on $element of the $group group\n"
done
done