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

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

问题描述

相当于 Python词典,但在Bash中(应该是

解决方案

Bash 4



Bash 4本身支持此功能。确保您的脚本的hashbang是#!/ usr / bin / env bash #!/ bin / bash 或任何否则引用 bash 而不是 sh 。确保你正在执行你的脚本,而不是像 sh脚本那样做一些愚蠢的事情,这将导致你的 bash hashbang被忽略。这是基本的东西,但是很多人仍然失败,因此重新迭代。



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

 声明-A动物

你可以使用正常的数组赋值运算符填充元素:

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

或合并他们:

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

然后像普通数组一样使用它们。 $ {animals [@]}展开值$ {!animals [@]}注意)扩展键。不要忘记引用他们:

  echo$ {animals [moo]}
${动物[@]!};做回声$ sound - $ {animals [$ sound]};完成



Bash 3



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



首先, em>:只要考虑升级到bash 4.认真的。

如果你有一些愚蠢的借口,为什么你无法升级 declare 更安全的选择。它不会将数据评估为像 eval 这样的bash代码,因此它不允许任意代码注入非常容易。



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



首先,间接(严重,不要使用这个,除非你有精神病或有其他不好的借口写作黑客)。

  $ animals_moo = cow;声音=も; I = animals_ $声音; echo$ {!i}
cow

其次,申报

  $ sound = moo;动物=牛;声明animals_ $ sound = $ animal; echo$ animals_moo
cow

将它们合在一起:

 #设置一个值:
declarearray_ $ index = $ value

#获取一个值:
arrayGet(){
local array = $ 1 index = $ 2
local i =$ {array} _ $ index
printf'%s'$ {!i}
}

让我们使用它:

  $ sound = moo 
$动物=牛
$声明animals_ $ sound = $动物
$ arrayGet动物$声音
cow

注意:声明不能放一个功能。在bash函数内部使用声明会将其创建的变量 local 转换为该函数的范围,这意味着我们无法访问或修改全局数组与它。 (在bash 4中,您可以使用declare -g来声明全局变量 - 但是在bash 4中,应该首先使用关联数组,而不是这个hack。)



摘要



升级到bash 4并使用 declare -A 。如果您不能,请考虑在执行上述丑恶攻击之前完全切换到 awk 。绝对保持远离 eval hackery。


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

解决方案

Bash 4

Bash 4 natively supports this feature. Make sure your script's hashbang is #!/usr/bin/env bash or #!/bin/bash or anything else that references bash and not sh. Make sure you're executing your script, and not doing something silly like sh script which would cause your bash hashbang to be ignored. This is basic stuff, but so many keep failing at it, hence the re-iteration.

You declare an associative array by doing:

declare -A animals

You can fill it up with elements using the normal array assignment operator:

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

Or merge them:

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

Then use them just like normal arrays. "${animals[@]}" expands the values, "${!animals[@]}" (notice the !) expands the keys. Don't forget to quote them:

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

Bash 3

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

First and foremost: Just consider upgrading to bash 4. Seriously. The future is now, stop living in the past and suffering from it by forcing stupid broken and ugly hacks on your code and every poor soul stuck maintaining it.

If you have some silly excuse why you "can't upgrade", declare is a far safer option. It does not evaluate data as bash code like eval does, and as such it does not allow arbitrary code injection quite so easily.

Let's prepare the answer by introducing the concepts:

First, indirection (seriously; never use this unless you're mentally ill or have some other bad excuse for writing hacks).

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

Secondly, declare:

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

Bring them together:

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

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

Let's use it:

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

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 should be using associative arrays in the first place, not this hack.)

Summary

Upgrade to bash 4 and use declare -A. If you can't, consider switching entirely to awk before doing ugly hacks as described above. And definitely stay the heck away from eval hackery.

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

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