連想配列をループして、その内容を一時配列に排出する必要があります(そして値の更新を実行します)。
次に、最初の配列の残りの内容を破棄する必要があります。一時配列を元の配列変数に割り当てたいと思います。
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)
連想配列では、反復する以外の方法はないと思います
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
これは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 |
拡張 Luca Borrione's cp_hash-これは私には機能せず、eval拡張の問題を追跡することを諦めました-bash4.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
これはどうですか(実際のコピーは作成せず、ソース変数へのリンクのみを作成します):
#!/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