如何比较 Bash 中两个不同关联数组之间的值?

How to compare values between two different associative arrays in Bash?

declare -A hm1
declare -A hm2
hm1["a"]=1
hm1["b"]=2
hm2["a"]=5
hm2["b"]=2

我想检查是否有相同的键,如果值不同则做一些事情

例如。 if [ hm1["a"] -eq hm2["a"] ] => implies if [ 1 == 5 ]; then do something ...

declare -A hm1
declare -A hm2
hm1["a"]=1
hm1["b"]=2
hm1["c"]=2
hm2["a"]=5
hm2["b"]=2

# compare values if exist and return 0/1
function areDifferent (){
    local key=
    # key does not exist in hm2
    [ -z ${hm2[$key]} ] && return 0 
    # compare values
    [ ${hm1[$key]} -ne ${hm2[$key]} ] && return 0 || return 1
}

# iterate through hm1 keys 
for k in ${!hm1[@]}
do
   # call compare function
   if areDifferent $k;
   then
    # areDifferent is true
    echo "values for key $k are different"
    # do some 
   fi
done

输出

values for key a are different
values for key c are different

假设:

  • 数组键可以包含白色 space
  • 数组不能包含同一组索引
  • 数组值可能不是数字(即,我们将比较字符串)

示例数据:

declare -A hm1
declare -A hm2

hm1["a"]=1
hm1["b"]=2
hm1["c d"]=3
hm1["e"]=12

hm2["a"]=5
hm2["b"]=2
hm2["c"]=7
hm2["e"]=twelve

获取所有索引的唯一列表:

$ printf "%s\n" "${!hm1[@]}" "${!hm2[@]}" | sort -u
a
b
c
c d
e

遍历执行适当测试的索引列表:

while read -r key
do
    [[ -z "${hm1[$key]}" ]] && echo "hm1[$key] does not exist" && continue
    [[ -z "${hm2[$key]}" ]] && echo "hm2[$key] does not exist" && continue

    [[ "${hm1[$key]}" == "${hm2[$key]}" ]] && echo "hm1[$key]=${hm1[$key]} == ${hm2[$key]}=hm2[$key]" && continue

    # at this point they are different so ...

    echo "hm1[$key]=${hm1[$key]} != ${hm2[$key]}=hm2[$key]"

done < <(printf "%s\n" "${!hm1[@]}" "${!hm2[@]}" | sort -u)

注意: remove/replace echo's 视情况而定

这会生成:

hm1[a]=1 != 5=hm2[a]
hm1[b]=2 == 2=hm2[b]
hm1[c] does not exist
hm2[c d] does not exist
hm1[e]=12 != twelve=hm2[e]

除了你的语法错误 - 在数字上下文之外,你会使用 ${hm1[a]} 而不是普通的 hm1["a"] 来引用你的变量,我建议你 do 在数字上下文中进行比较,因为在这种情况下你可以更简单地编写数组引用,即

if (( hm1[a] == hm2[a] ))
then 
  ...

代替繁琐

if [ ${hm1[a]} -eq ${hm2[a]} ]
then
  ....

当然要检查差异,您可以使用

if (( hm1[a] != hm2[a] ))
then 
  ...