繁体   English   中英

Bash 以列表为值的关联数组

[英]Bash associative array with list as value

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

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

但这会产生以下错误:

bash: syntax error near unexpected token `('

我可以逐行定义它,但我想把它放在一行中。 如何仅在一行中定义 bash 中的关联数组?

顺便说一句,关联数组、字典或映射 - 都属于一种抽象数据类型(我们称之为字典)。

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

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

"firstname middlename secondname"

作为X字典中s1键的值:

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]})

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

> echo ${names/__/ }
first name

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

> echo ${#names[@]}
3

在BASH中没有多维数组支持的情况下,您可以使用此循环关联数组。 关联数组中的每个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

一种更符合人体工程学的解决方案,不会强制操作按键。

# your data with spaces
array=(1 '2 with space' 3 "4 with space and ' symbol")
declare -p array

# quote it with " and store it, your data can't contain double quote
declare -A associative=([x]=x [array]=$(printf '"%s" ' "${array[@]}"))
declare -p associative

# get your data in another array
eval deserialized_array=(${associative[array]})
declare -p deserialized_array

echo ${deserialized_array[3]}

# or let bash handle everything

# note: array contain data with double quote character
array=(1 '2 with space' 3 "4 with space and ' \" symbol")

declare -A associative=([x]=x [array]=$(declare -p array))
declare -p associative

array=() # make sure data is gone

# get the data in the same array 
eval ${associative[array]}
echo ${array[3]}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM