How to rename an associative array in Bash?

后端 未结 8 2127
感情败类
感情败类 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: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
    

提交回复
热议问题