How to pass an associative array as argument to a function in Bash?

后端 未结 8 2143
自闭症患者
自闭症患者 2020-11-27 03:50

How do you pass an associative array as an argument to a function? Is this possible in Bash?

The code below is not working as expected:

function iter         


        
相关标签:
8条回答
  • 2020-11-27 04:35

    yo:

     #!/bin/bash
       declare -A dict
    
       dict=(
        [ke]="va"
        [ys]="lu"
        [ye]="es" 
       )
    
       fun() {
         for i in $@; do
           echo $i
         done
        }
    
       fun ${dict[@]} # || ${dict[key]} || ${!dict[@] || ${dict[$1]} 
    

    eZ

    0 讨论(0)
  • 2020-11-27 04:36

    If you're using Bash 4.3 or newer, the cleanest way is to pass the associative array by name and then access it inside your function using a name reference with local -n. For example:

    function foo {
        local -n data_ref=$1
        echo ${data_ref[a]} ${data_ref[b]}
    }
    
    declare -A data
    data[a]="Fred Flintstone"
    data[b]="Barney Rubble"
    foo data
    

    You don't have to use the _ref suffix; that's just what I picked here. You can call the reference anything you want so long as it's different from the original variable name (otherwise youll get a "circular name reference" error).

    0 讨论(0)
  • 2020-11-27 04:47

    I had exactly the same problem last week and thought about it for quite a while.

    It seems, that associative arrays can't be serialized or copied. There's a good Bash FAQ entry to associative arrays which explains them in detail. The last section gave me the following idea which works for me:

    function print_array {
        # eval string into a new associative array
        eval "declare -A func_assoc_array="${1#*=}
        # proof that array was successfully created
        declare -p func_assoc_array
    }
    
    # declare an associative array
    declare -A assoc_array=(["key1"]="value1" ["key2"]="value2")
    # show associative array definition
    declare -p assoc_array
    
    # pass associative array in string form to function
    print_array "$(declare -p assoc_array)" 
    
    0 讨论(0)
  • 2020-11-27 04:51

    Based on Florian Feldhaus's solution:

    # Bash 4+ only
    function printAssocArray # ( assocArrayName ) 
    {
        var=$(declare -p "$1")
        eval "declare -A _arr="${var#*=}
        for k in "${!_arr[@]}"; do
            echo "$k: ${_arr[$k]}"
        done
    
    }
    
    declare -A conf
    conf[pou]=789
    conf[mail]="ab\npo"
    conf[doo]=456
    
    printAssocArray "conf" 
    

    The output will be:

    doo: 456
    pou: 789
    mail: ab\npo
    
    0 讨论(0)
  • 2020-11-27 04:51

    Here is a solution I came up with today using eval echo ... to do the indirection:

    print_assoc_array() {
        local arr_keys="\${!$1[@]}" # \$ means we only substitute the $1
        local arr_val="\${$1[\"\$k\"]}"
        for k in $(eval echo $arr_keys); do #use eval echo to do the next substitution
            printf "%s: %s\n" "$k" "$(eval echo $arr_val)"
        done
    }
    
    declare -A my_arr
    my_arr[abc]="123"
    my_arr[def]="456"
    print_assoc_array my_arr
    

    Outputs on bash 4.3:

    def: 456
    abc: 123
    
    0 讨论(0)
  • 2020-11-27 04:53

    You can only pass associative arrays by name.

    It's better (more efficient) to pass regular arrays by name also.

    0 讨论(0)
提交回复
热议问题