【问题标题】:Bash indirect reference to an associative arrayBash 对关联数组的间接引用
【发布时间】:2015-02-11 22:47:33
【问题描述】:

在这个非常简化的示例中,我需要同时处理数组元素的键和值:

declare -A writer
writer[H.P.]=Lovecraft
writer[Stephen]=King
writer[Clive]=Barker
writer[Jack]=Ketchum

for i in ${!writer[@]}
do
    echo "$i ${writer[$i]}"
done

fullname()
{
    pointer=$1[@]
    for i in "${!pointer}"
    do
        echo "? $i"
    done
}
fullname writer

该函数必须以与前面的示例循环相同的格式显示输出,并且它应该接收数组名称、键或值列表,我尝试了所有这些,但没有成功。非常感谢任何建议。

【问题讨论】:

    标签: arrays bash pointers key associative-array


    【解决方案1】:
    indir_keys() {
        eval "echo \${!$1[@]}"
    }
    
    indir_val() {
        eval "echo \${$1[$2]}"
    }
    
    fullname()
    {
        pointer=$1
        for i in $(indir_keys $pointer)
        do  
            echo "$i $(indir_val $pointer $i)"
        done
    }
    

    给予:

    Jack Ketchum
    Clive Barker
    Stephen King
    H.P. Lovecraft
    

    【讨论】:

    • 通过验证$1$2只是 有效标识符,例如[[ $1 =~ [A-Za-z_][A-Za-z0-9_]+ ]] || return 之类的标识符,这可以变得更安全。
    【解决方案2】:

    来自Bash Reference Guide

    位置参数在执行 shell 函数时被临时替换(参见Shell Functions)。

    所以你可以这样做:

    fullname()
    {
        for first
        do
            echo "$first ${writer[$first]}"
        done
    }
    fullname "${!writer[@]}"
    

    【讨论】:

      【解决方案3】:

      从 Bash 4.3 开始,declare 有一个标志 -n 来定义引用(这大致相当于 C++ 中的引用)。此标志极大地简化了您的问题:

      fullname() {
          declare -nl pointer="$1"
          for i in "${!pointer[@]}"
          do
              echo "${pointer[$i]} $i"
          done
      }
      

      如果您的哈希键中有空格或有趣的符号(与接受的答案不同),那将是安全的。

      【讨论】:

      • 太好了,不知道这个新功能+1这应该是接受的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多