Bash:如何将一个关联数组赋值给另一个variables名(例如重命名该variables)?

我需要遍历一个关联数组,并将其内容耗尽到一个临时数组(并执行一些更新)。

第一个数组的剩余内容应该被丢弃,我想把temp数组赋给原来的数组variables。

Sudo代码:

declare -A MAINARRAY declare -A TEMPARRAY ... populate ${MAINARRAY[...]} ... while something; do #Drain some values from MAINARRAY to TEMPARRAY ${TEMPARRAY["$name"]}=((${MAINARRAY["$name"]} + $somevalue)) done ... other manipulations to TEMPARRAY ... unset MAINARRAY #discard left over values that had no update declare -A MAINARRAY MAINARRAY=${TEMPARRAY[@]} #assign updated TEMPARRAY back to MAINARRAY (ERROR HERE) 

Solutions Collecting From Web of "Bash:如何将一个关联数组赋值给另一个variables名(例如重命名该variables)?"

有了关联数组,我不相信除了迭代之外还有其他方法

 for key in "${!TEMPARRAY[@]}" # make sure you include the quotes there do MAINARRAY["$key"]="${TEMPARRAY["$key"]}" # or: MAINARRAY+=( ["$key"]="${TEMPARRAY["$key"]}" ) done 

复制关联数组在bash中不是直接可能的。 正如已经指出的那样,最好的解决方案可能是遍历数组并逐步复制它。

还有另一个解决方案, 我用它来传递变量的函数 。 您可以使用相同的技术来复制关联数组:

 # 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 

这一行代码执行关联数组副本:MAINARRAY = TEMPARRAY

 eval $(typeset -A -p TEMPARRAY|sed 's/ TEMPARRAY=/ MAINARRAY=/') 

在glenn jackman和ffeldhaus的建议之后,你可以建立一个可能变得方便的功能:

 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 } 

用法:

 declare -A copy_hash_name cp_hash 'original_hash_name' 'copy_hash_name' 

例:

 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 

会输出

 key : ab | value: cd key : hello | value: world 

在Luca Borrione的 cp_hash上扩展 – 这对我不起作用,我放弃了试图追踪eval扩展的问题 – 我在bash 4.2之前和之后遇到了差异。 在4.2(某事)之后,这变得更容易了…但是这不是向后兼容的。 见1和2

所以我的变化在4.1.2(1)和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 
 MAINARRAY=( "${TEMPARRAY[@]}" )