如何在Bash中定义散列表?

2024-03-29 06:23:41 发布

您现在位置:Python中文网/ 问答频道 /正文

什么是Python dictionaries的等价物,但在Bash中(应该可以跨OS X和Linux工作)。


Tags: bashoslinuxdictionaries
3条回答

这就是我要找的:

declare -A hashmap
hashmap["key"]="value"
hashmap["key2"]="value2"
echo "${hashmap["key"]}"
for key in ${!hashmap[@]}; do echo $key; done
for value in ${hashmap[@]}; do echo $value; done
echo hashmap has ${#hashmap[@]} elements

对于bash 4.1.5,这对我不起作用:

animals=( ["moo"]="cow" )

有参数替换,虽然它也可能是非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方法更好,但是如果你需要一个黑客…只有一个黑客可以。 您可以使用类似的技术搜索数组/散列。

猛击4

Bash 4本机支持这个特性。确保脚本的hashbang是#!/usr/bin/env bash#!/bin/bash,这样就不会使用sh。确保直接执行脚本,或者使用bash script执行script。(使用Bash不实际执行Bash脚本确实会发生的情况,而且会让感到困惑!)

通过执行以下操作声明关联数组:

declare -A animals

可以使用普通数组赋值运算符将其填充为元素。例如,如果要有animal[sound(key)] = animal(value)的映射:

animals=( ["moo"]="cow" ["woof"]="dog")

或者合并它们:

declare -A animals=( ["moo"]="cow" ["woof"]="dog")

然后像普通数组一样使用它们。使用

  • animals['key']='value'设置值

  • "${animals[@]}"展开值

  • "${!animals[@]}"(注意!)展开键

别忘了引用它们:

echo "${animals[moo]}"
for sound in "${!animals[@]}"; do echo "$sound - ${animals[$sound]}"; done

猛击3

在bash 4之前,没有关联数组。不要使用eval来模拟它们。避免像瘟疫一样,因为它是外壳脚本的瘟疫。最重要的原因是eval将数据视为可执行代码(还有许多其他原因)。

首先:考虑升级到bash 4。这将使整个过程对你来说容易得多。

如果有原因不能升级,declare是一个更安全的选择。它不像eval那样计算bash代码的数据,因此不允许非常容易地插入任意代码。

让我们通过介绍以下概念来准备答案:

首先,间接。

$ animals_moo=cow; sound=moo; i="animals_$sound"; echo "${!i}"
cow

其次,declare

$ sound=moo; animal=cow; declare "animals_$sound=$animal"; echo "$animals_moo"
cow

把他们聚在一起:

# Set a value:
declare "array_$index=$value"

# Get a value:
arrayGet() { 
    local array=$1 index=$2
    local i="${array}_$index"
    printf '%s' "${!i}"
}

让我们使用它:

$ sound=moo
$ animal=cow
$ declare "animals_$sound=$animal"
$ arrayGet animals "$sound"
cow

注意:declare不能放在函数中。在bash函数中使用declare会将它创建的变量local转到该函数的作用域,这意味着我们不能用它访问或修改全局数组。(在bash 4中,您可以使用declare-g来声明全局变量,但是在bash4中,您可以首先使用关联数组,从而避免这种解决方法。)

总结:

  • 升级到bash 4并对关联数组使用declare -A
  • 如果无法升级,请使用declare选项。
  • 考虑改用awk并完全避免这个问题。

相关问题 更多 >