什么是Python字典的等效,但在Bash中(应该适用于OS X和Linux)。


当前回答

我在bash 3中使用动态变量创建hashmap。我在我的回答中解释了它是如何工作的:Shell脚本中的关联数组

您还可以查看shell_map,它是bash 3中实现的HashMap。

其他回答

我在bash 3中使用动态变量创建hashmap。我在我的回答中解释了它是如何工作的:Shell脚本中的关联数组

您还可以查看shell_map,它是bash 3中实现的HashMap。

我真的很喜欢Al P的答案,但想要唯一性强制廉价,所以我更进一步-使用目录。有一些明显的限制(目录文件限制,无效的文件名),但它应该适用于大多数情况。

hinit() {
    rm -rf /tmp/hashmap.$1
    mkdir -p /tmp/hashmap.$1
}

hput() {
    printf "$3" > /tmp/hashmap.$1/$2
}

hget() {
    cat /tmp/hashmap.$1/$2
}

hkeys() {
    ls -1 /tmp/hashmap.$1
}

hdestroy() {
    rm -rf /tmp/hashmap.$1
}

hinit ids

for (( i = 0; i < 10000; i++ )); do
    hput ids "key$i" "value$i"
done

for (( i = 0; i < 10000; i++ )); do
    printf '%s\n' $(hget ids "key$i") > /dev/null
done

hdestroy ids

在我的测试中,它的表现也稍微好一点。

$ time bash hash.sh 
real    0m46.500s
user    0m16.767s
sys     0m51.473s

$ time bash dirhash.sh 
real    0m35.875s
user    0m8.002s
sys     0m24.666s

我只是想帮帮忙。干杯!

编辑:添加hdestroy()

这里有参数替换,尽管它也可能是非pc的…喜欢间接。

#!/bin/bash

# Array pretending to be a Pythonic dictionary
ARRAY=( "cow:moo"
        "dinosaur:roar"
        "bird:chirp"
        "bash:rock" )

for animal in "${ARRAY[@]}" ; do
    KEY="${animal%%:*}"
    VALUE="${animal##*:}"
    printf "%s likes to %s.\n" "$KEY" "$VALUE"
done

printf "%s is an extinct animal which likes to %s\n" "${ARRAY[1]%%:*}" "${ARRAY[1]##*:}"

BASH 4方式当然更好,但如果你需要一个hack…只有黑客才行。 您可以使用类似的技术搜索数组/散列。

我也使用了bash4的方式,但我发现了一个恼人的bug。

我需要动态更新关联数组内容,所以我使用这种方式:

for instanceId in $instanceList
do
   aws cloudwatch describe-alarms --output json --alarm-name-prefix $instanceId| jq '.["MetricAlarms"][].StateValue'| xargs | grep -E 'ALARM|INSUFFICIENT_DATA'
   [ $? -eq 0 ] && statusCheck+=([$instanceId]="checkKO") || statusCheck+=([$instanceId]="allCheckOk"
done

我发现,与bash 4.3.11附加到字典中的现有键导致附加值,如果已经存在。例如,在一些重复之后,值的内容是“checkKOcheckKOallCheckOK”,这是不好的。

使用bash 4.3.39没有问题,其中附加一个存在的键意味着替换已经存在的实际值。

我解决了这个问题,只是在循环之前清洗/声明statusCheck关联数组:

unset statusCheck; declare -A statusCheck

在bash 4之前,在bash中没有使用关联数组的好方法。最好的办法是使用一种真正支持这些功能的解释语言,比如awk。另一方面,bash 4确实支持它们。

至于bash 3中不太好的方法,这里有一个参考:http://mywiki.wooledge.org/BashFAQ/006