如果您提前声明数组,则 Bash 数组分配将失败
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28179409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash array assignment fails if you declare the array in advance
提问by Thanatos
This works:
这有效:
$ BAR=(a b c)
$ echo "${BAR[1]}"
b
This, however, doesn't:
然而,这不会:
$ 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
The docs claim the subscript is optional:
文档声称下标是可选的:
Arrays are assigned to using compound assignments of the form
name=(value1 ... valuen)
, where each value is of the form[subscript]=string
. Onlystring
is required.
数组被赋值为使用形式的复合赋值
name=(value1 ... valuen)
,其中每个值都是这种形式[subscript]=string
。仅string
是必需的。
What about the use of declare
changes the syntax of array assignment here? Why does hinting bash about the type of the variable with declare
change things? (Why does declare
exist at all?— if I assign an array to a variable, then the variable is an array… no?)
在这里使用declare
更改数组赋值的语法怎么样?为什么提示 bash 会declare
改变变量的类型?(为什么declare
存在?——如果我将一个数组赋给一个变量,那么该变量就是一个数组……不是吗?)
回答by Jonathan Leffler
declare -a
declares an array indexed by integers.
declare -a
声明一个由整数索引的数组。
declare -A
declares an associative array indexed by strings.
declare -A
声明一个由字符串索引的关联数组。
You have to use:
你必须使用:
FOO=([1]="a" [2 or 3]="b or c")
or similar notations to assign to the associative array, and:
或类似的符号分配给关联数组,以及:
echo "${FOO[2 or 3]}"
to access them.
访问它们。
回答by influxd
$ declare -A FOO
This is declaring an associative array. Note the difference in case, -a
is used to declare an (indexed) array.
这是声明一个关联数组。注意大小写的区别,-a
用于声明(索引)数组。
$ declare -a FOO
回答by anubhava
You cannot initialize simple index based array declared with -A
like that.
您不能初始化-A
这样声明的基于简单索引的数组。
Use this:
用这个:
declare -A foo
foo=( [x]="A" [y]="B" [z]="C" )
OR just:
要不就:
declare -A foo=( [x]="A" [y]="B" [z]="C" )
To use index based indices in an associative array use:
要在关联数组中使用基于索引的索引,请使用:
declare -A foo=( [0]="a" [1]="b" [2]="c" )
回答by vijayalakshmi d
You have used -A option which is creating associating array variable Instead, you should try creating array variable by using option -a.
您已经使用 -A 选项创建关联数组变量 相反,您应该尝试使用选项 -a 创建数组变量。
bash-3.2$ declare -a BOO
bash-3.2$ 声明 -a BOO
bash-3.2$ BOO=(a b c)
bash-3.2$ BOO=(abc)
bash-3.2$
bash-3.2$
bash-3.2$ echo "${BOO[1]}"
bash-3.2$ echo "${BOO[1]}"
b
乙
bash-3.2$ echo "${BOO[2]}"
bash-3.2$ echo "${BOO[2]}"
c
C
bash-3.2$
bash-3.2$
回答by dragon788
Per the other answers this is the difference between associative (key=value pairs) and indexed (index 0-infinity, value) arrays in Bash.
根据其他答案,这是 Bash 中关联(键=值对)和索引(索引 0-无穷大,值)数组之间的区别。
Now if you want to do a clever trick by building up an indexed array and converting it to an associative array later this is possible, though keep in mind the "values" that get converted to "keys" must be unique in the array or they will get overwritten unless you do some tracking of how many times a given "value" was seen and insert the indices into an array of values for each "key".
现在,如果您想通过构建索引数组并稍后将其转换为关联数组来做一个聪明的技巧,这是可能的,但请记住,转换为“键”的“值”在数组中必须是唯一的,否则它们除非您跟踪给定“值”的出现次数并将索引插入到每个“键”的值数组中,否则将被覆盖。
https://unix.stackexchange.com/a/177589
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