bash 数组的数组

bash 数组的数组

尝试编写一些嵌套循环,但我不知道如何编写它。也许我看错了方向,但我想写的是:

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

相关内容