我需要遍历一个关联数组并将其内容排放到临时数组(并对该值执行一些更新)。
然后应丢弃第一个数组的剩余内容,并且我想将temp数组分配给原始数组变量。
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)
答案 0 :(得分:23)
在bash中无法直接复制关联数组。正如已经指出的那样,最好的解决方案可能是迭代遍历数组并逐步复制它。
还有另一种解决方案I used to pass variables to functions。您可以使用相同的技术来复制关联数组:
# 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
答案 1 :(得分:12)
使用关联数组,我不相信除了迭代之外还有其他任何方法
for key in "${!TEMPARRAY[@]}" # make sure you include the quotes there
do
MAINARRAY["$key"]="${TEMPARRAY["$key"]}"
# or: MAINARRAY+=( ["$key"]="${TEMPARRAY["$key"]}" )
done
答案 2 :(得分:7)
这个单行执行关联数组副本:MAINARRAY = TEMPARRAY
eval $(typeset -A -p TEMPARRAY|sed 's/ TEMPARRAY=/ MAINARRAY=/')
答案 3 :(得分:2)
根据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
答案 4 :(得分:1)
扩展Luca Borrione's 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
答案 5 :(得分:1)
这个怎么样(没有创建真正的副本,只是源变量的链接):
#!/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']}
将打印:
value1
/tmp/log.txt
答案 6 :(得分:1)
这是一个小型复制函数,可用于任何形式的bash变量
-普通标量变量
-索引数组
-关联数组
### 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=}"
}
用法,示例:
# 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>
结果
--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 |
答案 7 :(得分:-2)
MAINARRAY=( "${TEMPARRAY[@]}" )