Bash:正确迭代Map的方法

6
在Bash中,我可以使用以下常用结构创建一个(哈希表)
hput() {
  eval "$1""$2"='$3'
}

hget() {
  eval echo '${'"$1$2"'#hash}'
}

然后像这样使用它:
hput capitals France Paris
hput capitals Spain Madrid
echo "$(hget capitals France)"

但是我该如何最好地迭代映射中的条目呢?例如,在Java中我会这样做:

for (Map.Entry<String, String> entry : capitals.entrySet()) {
  System.out.println("Country " + entry.getKey() + " capital " + entry.getValue());
}

有没有一种通用的方法可以在Bash中实现类似的功能?
3个回答

12
如果你有bash 4.0,你可以使用关联数组。否则,你可以利用awk的关联数组。

我正在使用Bash 3,因此awk解决方案看起来比自己编写的要好得多。谢谢。 - Lars Tackmann

4
这是一种方法实现它:
for h in ${!capitols*}; do indirect=$capitols$h; echo ${!indirect}; done

这里还有一个:

for h in ${!capitols*}; do key=${h#capitols*}; hget capitols $key; done

And another:

hiter() { 
    for h in $(eval echo '${!'$1'*}')
    do
        key=${h#$1*}
        echo -n "$key "
        hget $1 $key
    done
}
hiter capitols
France Paris
Spain Madrid

顺便说一下,“capitol”是指建筑物。城市被称为“capital”。

1
hkeys() {
    set | grep -o "^${1}[[:alnum:]]*=" | sed -re "s/^${1}(.*)=/\\1/g"
}
for key in $(hkeys capitols) ; do
    echo $key
done

而你的hget函数是错误的。试试这个:

hput capitols Smth hash
hget capitols Smth

第二个命令应该返回字符串哈希,但它没有返回任何内容。从您的函数中删除“#hash”字符串。

此外,echo "$(hget capitols France)" 是不明确的。您可以改用hget capitols France


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