如何在Bash中重命名关联数组?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Bash中重命名关联数组?相关的知识,希望对你有一定的参考价值。
我需要循环一个关联数组并将其内容排放到临时数组(并对该值执行一些更新)。
然后应该丢弃第一个数组的剩余内容,并且我想将temp数组分配给原始数组变量。
伪代码:
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中不能直接复制关联数组。正如已经指出的那样,最佳解决方案可能是迭代遍历数组并逐步复制它。
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
另一答案
这个单行做一个关联数组副本: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'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
另一答案
这个怎么样(不创建真正的副本,只是源变量的链接):
#!/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
另一答案
这是一个用于任何类型的bash-Variables的小型复制函数 - 正常的标量变量 - 索引数组 - 关联数组
### 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 |
另一答案
MAINARRAY=( "${TEMPARRAY[@]}" )
以上是关于如何在Bash中重命名关联数组?的主要内容,如果未能解决你的问题,请参考以下文章