壳中的Hashmap样式数组?

时间:2019-06-30 19:13:04

标签: bash shell

我是Shell的新手。我想创建一个哈希图样式的数组。

我已经看过这个How to define hash tables in Bash?

这不是我想要的。 这是我的期望:

myArray=(emma=paris, london, ny john=tokyo, LA)

#names are my keys and cities are my values

我的实际代码如下:

 declare -A myArray=( ["$names"]="$cities" )

它不起作用,因为每个新城市都会覆盖最后一个城市。

3 个答案:

答案 0 :(得分:0)

danaso,您是否引用了每个人的城市列表,还是分别引用了每个城市?当我做前者时,事情似乎对我来说很好。这是我的Bash会话的(略作编辑的)成绩单:

$  declare -A myArray=([emma]="paris london ny" [john]="tokyo LA")

或者,要像在“实际代码”中一样,从称为namescities的常规数组中快速创建关联数组,您首先要创建这些数组,如下所示:< / p>

$ declare -a names=(emma john)                     # Notice: small '-a' for inexed array.
$ declare -a cities=("paris london ny" "tokyo LA") # Notice: Quotes around whole lists of cities!

然后,我将从一个空的myArray开始,然后像这样循环构建它:

$ declare myArray=()

for i in ${!names[@]}; do
      name=${names[$i]}
      city=${cities[$i]}
     myArray+=([$name]=$city)
done

顺便说一句:在将来的某个时候,您可能希望以这种方式填充myArray,但是在citiesnames中会有不同的条目。如果这样做的话,在set -o noglob循环之前使用for是一个很好的想法。这会禁用外壳程序对路径名的扩展,并且当您在其中一个数组中意外包含名为*的名称或城市时,可以防止出现麻烦。您可以在set +o noglob循环之后使用for重新启用它。

无论如何,无论您以哪种方式填充myArray,新城市都不会再覆盖以前的城市,如您所见:

$  echo ${myArray[emma]}
paris london ny    

$ echo ${myArray[john]}
tokyo LA

您可以单独处理城市,例如在此for循环中:

$ for city in ${myArray[emma]}; do echo "hello, $city!";  done
hello, paris!
hello, london!
hello, ny!

如何为您工作?

PS:我要感谢Charles Duffy在评论中建议的对我的代码的改进。

答案 1 :(得分:0)

Bash 4支持关联数组。但是,如果使用Bash 3或更低版本,则可以使用常规数组来滚动自己的结构,然后在某个分隔符(例如=)上拆分每个元素。

#!/bin/bash

array=(
  emma="paris london ny" 
  john="tokyo LA"
)

for item in "${array[@]}"; do 
  key=$(cut -d "=" -f 1 <<< "$item")
  value=$(cut -d "=" -f 2 <<< "$item")
  echo "$key=$value"
done 

示例输出:

emma=paris london ny
john=tokyo LA

答案 2 :(得分:0)

arrayName["$key"]="$value"语法仅应在打算完全替换变量的内容时使用,覆盖所有先前存在的值,仅保留声明中描述的那些值。

如果您想随时间添加新值,请使用declare -A arrayName=( ) # Initialize an empty associative array arrayName["key1"]=value1 # add key1 arrayName["key2"]=value2 # add key2 arrayName["key3"]=value3 # add key3 declare -p arrayName # print resulting array 。因此:

# initialize with all three values already present
declare -A arrayName=( ["key1"]="value1" ["key2"]="value2" ["key3"]="value3" )
declare -p arrayName       # print resulting array

...具有与以下相同的结果:

declare -A arrayName=( ["key1"]="value1" )  # initialize with key1=value1
declare -A arrayName=( ["key2"]="value2" )  # discard and overwrite with key2=value2
declare -A arrayName=( ["key3"]="value3" )  # discard and overwrite with key3=value3
declare -p arrayName                        # output only has key3 and value3!

...而以下内容则丢弃除最后一个以外的所有内容:

{{1}}