【问题标题】:Bash array assignment fails if you declare the array in advance如果提前声明数组,bash 数组赋值失败
【发布时间】:2015-03-26 14:16:34
【问题描述】:

这行得通:

$ 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 暗示变量的类型会改变事情? (为什么declare 存在——如果我将一个数组分配给一个变量,那么该变量就是一个数组……不?)

【问题讨论】:

    标签: arrays bash associative-array


    【解决方案1】:

    请注意,在我的情况下,我收到此错误是因为在 = 之前和之后我添加了一个空格。

    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
    

    【讨论】:

      【解决方案2】:

      根据其他答案,这是 Bash 中关联(键=值对)和索引(索引 0-infinity,值)数组之间的区别。

      现在,如果您想通过构建索引数组并稍后将其转换为关联数组来做一个聪明的技巧,这是可能的,但请记住,转换为“键”的“值”必须是唯一的数组,否则它们将被覆盖,除非您跟踪查看给定“值”的次数并将索引插入到每个“键”的值数组中。

      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
      

      【讨论】:

        【解决方案3】:

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

        bash-3.2$ 声明 -a BOO

        bash-3.2$ BOO=(a b c)

        bash-3.2$

        bash-3.2$ echo "${BOO[1]}"

        b

        bash-3.2$ echo "${BOO[2]}"

        c

        bash-3.2$

        【讨论】:

          【解决方案4】:
          $ declare -A FOO
          

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

          $ declare -a FOO
          

          【讨论】:

          • 啊!我没有意识到 bash 有单独的“索引”和“关联”概念(我认为它更像是 PHP 风格……)
          【解决方案5】:

          您不能像这样初始化使用-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" )
          

          【讨论】:

            【解决方案6】:

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

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

            你必须使用:

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

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

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

            访问它们。

            【讨论】:

            • 啊!我没有意识到 bash 有单独的“索引”和“关联”概念(我认为它更像是 PHP 风格……)
            猜你喜欢
            • 2014-05-23
            • 2010-10-19
            • 1970-01-01
            • 2010-12-10
            • 2010-12-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多