如何在bash中检查字典是否包含某个键?

6
我想检查一个字典是否包含某个键,但我不知道怎么做。 我尝试了以下代码:
if [ -z "${codeDict["$STR_ARRAY[2]"]+xxx}" ]
then
    echo "codeDict not contains ${STR_ARRAY[2]}"
    codeDict["${STR_ARRAY[2]}"]="${STR_ARRAY[3]}"
fi

1
你在测试中的STR_ARRAY扩展上错过了{} - Etan Reisner
哦......非常感谢! - just
2个回答

6

您的方法没有问题(使用-z),正如这个例子所示:

$ declare -A a
$ a=( [a]=1 [b]=2 [d]=4 )
$ [[ -z ${a[a]} ]] && echo unset
$ [[ -z ${a[c]} ]] && echo unset
unset

然而,你提供的代码存在一些问题。你的内部数组缺少花括号,我个人建议使用扩展测试([[ 而不是 [)以避免在引号上费心:

$ str=( a b c )
$ [[ -z ${a[${str[0]}]} ]] && echo unset
$ [[ -z ${a[${str[2]}]} ]] && echo unset
unset

3
它无法区分缺失的条目和值为空字符串的条目。 - Keith Thompson

5

如果您正在使用 bash 4.3,可以使用 -v 测试:

if [[ -v codeDict["${STR_ARRAY[2]}"] ]]; then
    # codeDict has ${STR_ARRAY[2]} as a key
else
    # codeDict does not have ${STR_ARRAY[2]} as a key
fi

否则,您需要注意区分映射到空字符串的键和根本不在数组中的键。
key=${STR_ARRARY[2]}
tmp=codeDict["$key"]  # Save a lot of typing
# ${!tmp} expands to the actual value (which may be the empty string),
#         or the empty string if the key does not exist
# ${!tmp-foo} expands to the actual value (which may be the empty string),
#             or "foo" if the key does not exist
# ${!tmp:-foo} expands to the actual value if it is a non-empty string,
#              or "foo" if the key does not exist *or* the key maps
#              to the empty string.
if [[ ${!tmp} = ${!tmp-foo} || ${!tmp} = ${!tmp:-foo} ]]; then
    # $key is a key
else
    # $key is not a key
fi

在支持关联数组的任何版本的中,如果您只想为不存在的键提供默认值,则可以使用简单的一行代码。
: ${codeDict["${STR_ARRAY[2]}"]="${STR_ARRAY[3]}"}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接