How to rename an associative array in Bash?

后端 未结 8 2106
感情败类
感情败类 2020-12-08 21:51

I need to loop over an associative array and drain the contents of it to a temp array (and perform some update to the value).

The leftover contents of the first arra

相关标签:
8条回答
  • 2020-12-08 22:34

    This one-liner does an associative array copy: MAINARRAY=TEMPARRAY

    eval $(typeset -A -p TEMPARRAY|sed 's/ TEMPARRAY=/ MAINARRAY=/')
    
    0 讨论(0)
  • 2020-12-08 22:36

    How about this one (Doesn't create a real copy, just a link to source variable):

    #!/bin/bash
    declare -A my_array=(["key1"]="value1" ["key2"]="value2")
    declare -n arr=my_array
    arr['LOG_FILE']=/tmp/log.txt
    echo ${arr['key1']}
    echo ${arr['LOG_FILE']}
    

    Will print:

    value1
    /tmp/log.txt
    
    0 讨论(0)
  • 2020-12-08 22:40

    Here is a small Copy-Function for bash-Variables of any kind
    - normal scalar variables
    - indexed arrays
    - associative arrays

    ### Function vcp    -VariableCoPy-  
    # $1 Name of existing Source-Variable  
    # $2 Name for the Copy-Target  
    vcp() {
        local var=$(declare -p $1)
        var=${var/declare /declare -g }
        eval "${var/$1=/$2=}"
    }
    

    Usage, Examples:

    # declarations
    var="  345  89  "
    ind_array=(Betty "  345  89  ")
    declare -A asso_array=([one]=Harry [two]=Betty [some_signs]=" +*.<\$~,'/ ")  
    
    # produce the copy
    vcp var varcopy
    vcp ind_array ind_array_copied
    vcp asso_array asso_array_2   
    
    # now you can check the equality between original and copy with commands like
    # declare -p <name>
    

    The results

    --3    1: "${asso_array[@]}"   
    (5)       asso_array[one]:        |Harry|   
    (11)      asso_array[some_signs]: | +*.<$~,'/ |   
    (5)       asso_array[two]:        |Betty|   
    --3    4: "${asso_array_2[@]}"   
    (5)       asso_array_2[one]:        |Harry|   
    (11)      asso_array_2[some_signs]: | +*.<$~,'/ |   
    (5)       asso_array_2[two]:        |Betty|   
    --2    7: "${ind_array[@]}"   
    (5)       ind_array[0]:   |Betty|   
    (11)      ind_array[1]:   |  345  89  |   
    --2    9: "${ind_array_copied[@]}"   
    (5)       ind_array_copied[0]:   |Betty|   
    (11)      ind_array_copied[1]:   |  345  89  |   
    (11)  11: "$var":   |  345  89  |  
    (11)  12: "$varcopy":   |  345  89  |  
    
    0 讨论(0)
  • 2020-12-08 22:40

    expanding on Luca Borrione's cp_hash - which didn't work for me, and I gave up trying to track down the eval expansion issue - I ran into differences before and after bash 4.2. after 4.2(something) this gets a lot easier... but that's not backwards compatible. See 1 and 2

    so my variation tested on 4.1.2(1) and 4.3.46(1):

    #!/bin/bash
    ## bash4 due to associative arrays!
    
        function cp_hash() {
            ## REQUIRES you to declare -A $2 in advance.
            local original_hash_name="$1"
            local copy_hash_name="$2"
            #
            # sadly we have no way to identify if you have already declared it, so bull ahead.
            #
            ## store the definition of the old array
            local __copy__=$(declare -p $original_hash_name)
            ## rename the array inside the definition
            __copy__=${__copy__/${original_hash_name}=/__copy__=}
    
            ## for bash 4.2 > we could end here.
            ## declare -A creates local scope variables by default, so add -g
            ## this DOES NOT work prior to 4.2, even w/o -g and w/ a declare outside.
            #    __copy__=${__copy__/${original_hash_name}=/${copy_hash_name}=}
            #    eval ${__copy__/-A/-g -A}
    
            ## for bash4 where we can't do -g, then:
            ## local associative array based on the definition we stored and modified
            eval ${__copy__}
            ## loop through the local copy, and store it in the declared-outside copy.
            for i in "${!__copy__[@]}"
            do
                eval ${copy_hash_name}[$i]=${__copy__[$i]}
            done
        }
    
        declare -A hash
        hash[hello]=world
        hash[ab]=cd
    
        #not required for 4.2+ if you use -g, neither helps nor hinders
        declare -A copy
    
        cp_hash 'hash' 'copy'
    
        echo hash: ${hash[@]}
        echo copy: ${copy[@]}
    
        echo "copy result loop"
        for i in "${!copy[@]}"
        do
            echo "key  : $i | value: ${copy[$i]}"
        done
    
    0 讨论(0)
  • 2020-12-08 22:45

    Following both the suggestions of glenn jackman and ffeldhaus, you can build a function which might become handy:

    function cp_hash
    {
        local original_hash_name="$1"
        local copy_hash_name="$2"
    
        local __copy__=$(declare -p $original_hash_name);
        eval declare -A __copy__="${__copy__:$(expr index "${__copy__}" =)}";
    
        for i in "${!__copy__[@]}"
        do
            eval ${copy_hash_name}[$i]=${__copy__[$i]}
        done
    }
    


    Usage:

    declare -A copy_hash_name
    cp_hash 'original_hash_name' 'copy_hash_name'
    


    Example:

    declare -A hash
    hash[hello]=world
    hash[ab]=cd
    
    declare -A copy
    cp_hash 'hash' 'copy'
    
    for i in "${!copy[@]}"
    do
        echo "key  : $i | value: ${copy[$i]}"
    done
    


    Will output

    key  : ab | value: cd
    key  : hello | value: world
    
    0 讨论(0)
  • 2020-12-08 22:52

    Copying associative arrays is not directly possible in bash. The best solution probably is, as already been pointed out, to iterate through the array and copy it step by step.

    There is another solution which I used to pass variables to functions. You could use the same technique for copying associative arrays:

    # declare associative array
    declare -A assoc_array=(["key1"]="value1" ["key2"]="value2")
    # convert associative array to string
    assoc_array_string=$(declare -p assoc_array)
    # create new associative array from string
    eval "declare -A new_assoc_array="${assoc_array_string#*=}
    # show array definition
    declare -p new_assoc_array
    
    0 讨论(0)
提交回复
热议问题