如果提前声明数组,Bash数组赋值将失败

时间:2015-01-27 20:30:02

标签: arrays bash associative-array

这有效:

$ BAR=(a b c)
$ echo "${BAR[1]}"
b

然而,这不是:

$ declare -A FOO
$ FOO=(a b c)
bash: FOO: a: must use subscript when assigning associative array
bash: FOO: b: must use subscript when assigning associative array
bash: FOO: c: must use subscript when assigning associative array

文档声称下标是可选的:

  

指定数组使用name=(value1 ... valuen)形式的复合赋值,其中每个值的格式为[subscript]=string。只需要string

使用declare如何更改数组赋值的语法?为什么用declare改变事物来暗示关于变量类型的bash? (为什么declare完全存在 - 如果我将数组赋给变量,那么变量就是数组......不是吗?)

6 个答案:

答案 0 :(得分:10)

declare -a声明一个由整数索引的数组。

declare -A声明一个由字符串索引的关联数组。

你必须使用:

FOO=([1]="a" [2 or 3]="b or c")

或类似的符号分配给关联数组,并且:

echo "${FOO[2 or 3]}"

访问它们。

答案 1 :(得分:4)

$ declare -A FOO

这是声明一个关联数组。请注意大小写的差异,-a用于声明(索引)数组。

$ declare -a FOO

答案 2 :(得分:4)

您无法初始化使用-A声明的基于简单索引的数组。

使用此:

declare -A foo
foo=( [x]="A" [y]="B" [z]="C" )

或者只是:

declare -A foo=( [x]="A" [y]="B" [z]="C" )

要在关联数组中使用基于索引的索引,请使用:

declare -A foo=( [0]="a" [1]="b" [2]="c" )

答案 3 :(得分:1)

您已使用-A选项创建关联数组变量 相反,您应该尝试使用选项-a。

创建数组变量

bash-3.2 $声明-a BOO

bash-3.2 $ BOO =(a b c)

的bash-3.2 $

bash-3.2 $ echo“$ {BOO [1]}”

B'/ P>

bash-3.2 $ echo“$ {BOO [2]}”

C

的bash-3.2 $

答案 4 :(得分:1)

在其他答案中,这是Bash中关联(键=值对)和索引(索引0-无穷大,值)数组之间的差异。

现在,如果您想通过建立索引数组并稍后将其转换为关联数组来做一个巧妙的技巧,尽管记住要转换为“键”的“值”必须在代码中是唯一的数组,否则它们将被覆盖,除非您对某个给定的“值”进行多少次跟踪并将每个索引的“索引”插入值数组中。

https://unix.stackexchange.com/a/177589

declare -a array1
array1=() # Empty the array to avoid repeated runs introducing side effects

# Using `+=($stuff)` adds to an array, using `+=$stuff` concatenates text
# if $stuff might have spaces, double quote it! or just always quote!
# see the tricky 'bar baz' with a space
for eachword in foo 'bar baz' fizzbuzz; do array1+=("$eachword"); done

# Make SURE you quote the array when looping over in case values have spaces
for eachword in "${array1[@]}"; do echo "$eachword"; done

declare -A map    # required: declare explicit associative array

for key in "${!array1[@]}"     # expand the array indexes to a list of words
do
  # Check uniqueness note
  map[${array1[$key]}]="$key"  # exchange the value ${array1[$key]} with the index $key
done

# Debug printing the new associative array
for eachkey in "${!map[@]}"; do echo "${eachkey}"; done
for eachvalue in "${map[@]}"; do echo "${eachvalue}"; done

a=fizzbuzz
[[ -n "${map[$a]}" ]] && printf '%s is in array\n' "$a"

# UNIQUENESS NOTE
# Add code before the map if you won't have unique "keys"
# It should check if the $array1[$key] already exists and make its "value"  an array where you append every new index where it existed
# NOTE: there may be some limitations with nested arrays in Bash

答案 5 :(得分:0)

小心,就我而言,我收到此错误是因为在 = 之前和之后我都添加了一个空格。

declare -A table_queries=(
    ["cluster"] = "select * from cluster where report_version_id = $REPORT_VERSION_ID"
) # Incorrect

declare -A table_queries=(
    ["cluster"]="select * from cluster where report_version_id = $REPORT_VERSION_ID"
) # Correct