以列表作为值的Bash关联数组

时间:2016-10-17 14:09:13

标签: arrays bash dictionary associative-array

我必须使用Java工具的输出,它返回一个看起来像HashMap<String, ArrayList<String>的地图数据结构。我必须使用BASH并尝试将其声明为关联数组,这与地图非常相似。 bash中关联数组的声明应该在一行中,我尝试按照以下方式执行此操作。

ARRAY=(["sem1"]=("first name" "second name") ["sem2"]=("third name") ["sem3]=OTHER_LITS)

但是这会产生以下错误:

bash: syntax error near unexpected token `('

我可以逐行定义,但我希望将它放在一行中。如何在bash中仅在一行中定义一个assoviative数组?

2 个答案:

答案 0 :(得分:2)

如果BASH中没有多维数组支持,您可以使用 word-around 关联数组。关联数组中的每个key都是map-index,array-list-index

的字符串连接
# use one line declaration
declare -A array=([sem1,0]="first name" [sem1,1]="second name" [sem2,0]="third name" [sem3,0]="foo bar")

# loop thrpugh the map array
for i in "${!array[@]}"; do echo "$i => ${array[$i]}"; done
sem2,0 => third name
sem1,0 => first name
sem1,1 => second name
sem3,0 => foo bar

答案 1 :(得分:1)

BTW,关联数组,字典或地图-都属于一种抽象数据类型(我们称其为 dictionary )。

因此,这是将 array 作为值存储在Bash(4+版本)的字典中的解决方案。

请注意,Bash中的 array 是用空格分隔的字符串列表(因此元素内没有任何空格,即字符串),因此我们可以编写一个带引号的列表:

"firstname middlename secondname"

作为s1字典中X键的值:

declare -A X=(
  ['s1']="firstname middlename secondname"
  ['s2']="surname nickname"
  ['s3']="other"
)

现在我们可以将s1键的值作为数组了:

declare -a names=(${X[s1]})

变量names现在包含数组

> echo $names
firstname

> echo ${names[1]}
middlename

> echo ${#names[@]}
3

最后,您的问题部分是显示带空格的字符串的地方:

"first name""second name"

让我们做个窍门-将空格表示为特殊的符号序列(可能只是一个符号),例如,双下划线:

"first__name""second__name"

再次声明我们的字典,但在数组元素内留有“转义”空格:

declare -A X=(
  ['s1']="first__name middle__name second__name"
  ['s2']="surname nickname"
  ['s3']="other"
)

在这种情况下,我们获得了s1键的值作为数组:

declare -a names=(${X[s1]})

我们需要对数组元素进行后期处理,以删除__对实际 space 符号的空格替换。为此,我们只需使用Bash字符串的替换命令:

> echo ${names/__/ }
first name

> echo ${names[1]/__/ }
middle name

> echo ${#names[@]}
3