【问题标题】:Bash scripting - Iterating through "variable" variable names for a list of associative arraysBash 脚本 - 遍历关联数组列表的“变量”变量名
【发布时间】:2012-10-29 15:12:45
【问题描述】:

我有一个关联数组的变量列表,我想遍历并检索它们的键/值对。

我通过列出其所有键并获取值来遍历单个关联数组,即。

for key in "${!queue1[@]}" do
    echo "key : $key"
    echo "value : ${queue1[$key]}"
done

棘手的部分是关联数组的名称是可变变量,例如给定计数 = 5,关联数组将命名为 queue1、queue2、queue3、queue4、queue5。

我正在尝试根据计数替换上面的序列,但到目前为止,括号和 eval 的每个组合并没有产生比错误替换错误更多的错误。例如下面:

for count in {1,2,3,4,5} do
    for key in "${!queue${count}[@]}" do
        echo "key : $key"
        echo "value : ${queue${count}[$key]}"
    done
done

非常感谢您的帮助!

【问题讨论】:

  • 在 bash 4.3(及更高版本)支持 namevar 的情况下,现有答案在很大程度上已经过时了。

标签: linux bash unix associative-array


【解决方案1】:

我能够使用以下脚本使其工作:

for count in {1..5} ; do
    for key in $(eval echo '${!q'$count'[@]}') ; do
        eval echo '${q'$count"[$key]}"
    done
done

请注意,如果任何键包含空格,则会中断。如果您想处理复杂的数据结构,请使用更强大的语言,例如 Perl。

【讨论】:

    【解决方案2】:

    这里的困难源于间接扩展的语法 (${!nameref}) 与从关联数组中提取键的语法 (${!array[@]}) 冲突。我们只能有一个或另一个,不能同时拥有。

    由于我对使用 eval 持谨慎态度,我看不到使用它来提取间接引用的关联数组的键的方法:

    keyref="queue${count}[@]"
    for key in $(eval echo '${!'$keyref'}'); do ... ; done
    

    但是,当从给定键的数组中提取值时,您可以避免使用eval 并使用间接扩展。请注意,[key] 后缀必须是扩展的一部分:

    valref="queue${count}[$key]"
    echo ${!valref}
    

    把它放在上下文中:

    for count in {1..5} ; do
        keyref="queue${count}[@]"
        for key in $(eval echo '${!'$keyref'}'); do
            valref="queue${count}[$key]"
            echo "key = $key"
            echo "value = ${!valref}"
        done
    done
    

    【讨论】:

      【解决方案3】:

      我认为这可能有效(但未经测试)。关键是对待索引 作为变量的全名。 (即数组queue5可以是 被视为一个名为queue5[this]queue5[that]等的变量序列)

      for count in {1,2,3,4,5} do
          assoc="queue$count[@]"
          for key in "${!assoc}" do
              echo "key : $key"
              val="queue$count[$key]"
              echo "value : ${!val}"
          done
      done
      

      【讨论】:

      • 这似乎遍历了数组中的值(而不是数组中的键)。我想您可以通过一些工作使用该值来挖掘密钥,但非唯一值可能存在问题。
      • 间接引用适用于访问数组值,但不适用于键。详情见我的回答。
      猜你喜欢
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 2020-03-07
      • 1970-01-01
      • 1970-01-01
      • 2014-02-21
      • 2014-11-04
      • 1970-01-01
      相关资源
      最近更新 更多