如何在 Bash 中定义哈希表? [英] How to define hash tables in Bash?

查看:36
本文介绍了如何在 Bash 中定义哈希表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Python 词典 的等价物是什么,但在 Bash 中(应该适用于 OS X 和 Linux).

What is the equivalent of Python dictionaries but in Bash (should work across OS X and Linux).

推荐答案

Bash 4

Bash 4 本身就支持这个特性.确保你的脚本的 hashbang 是 #!/usr/bin/env bash#!/bin/bash 这样你就不会最终使用 sh.确保您要么直接执行脚本,要么使用 bash script 执行 script.(实际上并没有使用 Bash 执行 Bash 脚本确实会发生,并且会真的令人困惑!)

Bash 4

Bash 4 natively supports this feature. Make sure your script's hashbang is #!/usr/bin/env bash or #!/bin/bash so you don't end up using sh. Make sure you're either executing your script directly, or execute script with bash script. (Not actually executing a Bash script with Bash does happen, and will be really confusing!)

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

You declare an associative array by doing:

declare -A animals

您可以使用普通的数组赋值运算符用元素填充它.例如,如果你想要一个 animal[sound(key)] = animal(value) 的地图:

You can fill it up with elements using the normal array assignment operator. For example, if you want to have a map of animal[sound(key)] = animal(value):

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

或者在一行中声明和实例化:

Or declare and instantiate in one line:

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

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

Then use them just like normal arrays. Use

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

"${animals[@]}" 扩展值

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

不要忘记引用它们:

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

重击 3

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

Bash 3

Before bash 4, you don't have associative arrays. Do not use eval to emulate them. Avoid eval like the plague, because it is the plague of shell scripting. The most important reason is that eval treats your data as executable code (there are many other reasons too).

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

First and foremost: Consider upgrading to bash 4. This will make the whole process much easier for you.

如果您因某种原因无法升级,declare 是更安全的选择.它不像 eval 那样像 bash 代码那样评估数据,因此不允许任意代码注入那么容易.

If there's a reason you can't upgrade, declare is a far safer option. It does not evaluate data as bash code like eval does, and as such does not allow arbitrary code injection quite so easily.

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

Let's prepare the answer by introducing the concepts:

首先,间接.

$ 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 来声明全局变量 - 但在 bash 4 中,您可以首先使用关联数组,从而避免这种变通方法.)

Note: declare cannot be put in a function. Any use of declare inside a bash function turns the variable it creates local to the scope of that function, meaning we can't access or modify global arrays with it. (In bash 4 you can use declare -g to declare global variables - but in bash 4, you can use associative arrays in the first place, avoiding this workaround.)

总结:

  • 升级到 bash 4 并对关联数组使用 declare -A.
  • 如果您无法升级,请使用 declare 选项.
  • 考虑改用 awk 并完全避免这个问题.
  • Upgrade to bash 4 and use declare -A for associative arrays.
  • Use the declare option if you can't upgrade.
  • Consider using awk instead and avoid the issue altogether.

这篇关于如何在 Bash 中定义哈希表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆