【问题标题】:Add a new element to an array without specifying the index in Bash在 Bash 中不指定索引的情况下向数组添加新元素
【发布时间】:2010-12-29 10:04:48
【问题描述】:

有没有办法在 bash vs 中做类似 PHPs $array[] = 'foo'; 的事情:

array[0]='foo'
array[1]='bar'

【问题讨论】:

标签: bash arrays


【解决方案1】:

是的,有:

ARRAY=()
ARRAY+=('foo')
ARRAY+=('bar')

Bash Reference Manual:

在赋值语句为 shell 变量或数组索引(请参阅数组)赋值的上下文中,“+=”运算符可用于附加或添加到变量的前一个值。

【讨论】:

  • 这适用于 bash 3.2.48 (OS X 10.8.2)。请注意,ARRAY 只是实际变量名称的占位符。即使您的数组索引不是连续的,附加+= 也只会分配给最高索引+ 1。
  • 在 bash 版本 4.2.24(1) 中有类似的东西吗?
  • 值得注意的是,ARRAY+=('foo') 与 ARRAY+='foo' 不同,后者将字符串 'foo' 附加到具有最低 (?) 键的条目中。
  • 根据wiki.bash-hackers.org/scripting/bashchanges,这个语法最早出现在3.1-alpha1版本。
  • @Jas:要访问 整个 数组,您必须使用${myarray[@]} - 像访问标量一样引用数组变量与访问其元素 0 相同;换句话说:$myarray 与 ${myarray[0]} 相同。
【解决方案2】:

正如 Dumb Guy 所指出的,重要的是要注意数组是否从零开始并且是连续的。由于您可以对非连续索引进行分配和取消设置,因此${#array[@]} 并不总是数组末尾的下一项。

$ array=(a b c d e f g h)
$ array[42]="i"
$ unset array[2]
$ unset array[3]
$ declare -p array     # dump the array so we can see what it contains
declare -a array='([0]="a" [1]="b" [4]="e" [5]="f" [6]="g" [7]="h" [42]="i")'
$ echo ${#array[@]}
7
$ echo ${array[${#array[@]}]}
h

获取最后一个索引的方法如下:

$ end=(${!array[@]})   # put all the indices in an array
$ end=${end[@]: -1}    # get the last one
$ echo $end
42

这说明了如何获取数组的最后一个元素。你会经常看到这样的:

$ echo ${array[${#array[@]} - 1]}
g

如您所见,因为我们处理的是稀疏数组,所以这不是最后一个元素。不过,这适用于稀疏数组和连续数组:

$ echo ${array[@]: -1}
i

【讨论】:

  • 好东西;从来不知道子字符串提取语法也可以应用于数组;通过反复试验确定的规则是(bash 3.2.48):${array[@]: start[:count]} 返回计数元素。或者,如果没有指定,所有 remaining 元素。从以下元素开始: - 如果开始 >= 0:从元素开始。其索引 >= start。 - 如果 start (last array index + 1),则返回空字符串。如果指定了 count,则返回尽可能多的元素,即使它们的索引从一开始就不连续。
  • @mklement:在 Bash 4.2 中,您可以使用负数组下标来访问从数组末尾开始计数的元素。 ${array[-1]}
  • 很高兴知道,谢谢。 OS X(从 10.8.2 开始)仍然使用 3.2.48,stackoverflow.com/questions/10418616/… 告诉我,不幸的是,“Apple 使用相当旧的 Bash 版本,因为他们不发布根据 GPL3 许可的代码。”跨度>
【解决方案3】:
$ declare -a arr
$ arr=("a")
$ arr=("${arr[@]}" "new")
$ echo ${arr[@]}
a new
$ arr=("${arr[@]}" "newest")
$ echo ${arr[@]}
a new newest

【讨论】:

  • 非常适合不支持 e-t172 解释的 += 运算符语义的 bash 版本
  • 一个很好的向后兼容解决方案,但要注意,如果任何现有元素中有空格,它们将被拆分为多个元素;如果元素中有空格,请使用arr=("${arr[@]}" "new")
  • 这个也可以用来推到数组前面,正是我需要的。
【解决方案4】:

如果您的数组始终是连续的并且从 0 开始,那么您可以这样做:

array[${#array[@]}]='foo'

# gets the length of the array
${#array_name[@]}

如果不小心在等号之间使用了空格:

array[${#array[@]}] = 'foo'

然后你会收到类似如下的错误:

array_name[3]: command not found

【讨论】:

  • 是的,你可以,但是+= 语法(参见@e-t172 的答案)更简单,并且(b)也适用于不连续和/或不连续的数组不以 0 开头。
  • 老实说,这个解决方案(对我来说)比“+=”工作得更好,因为后者的长度有时是错误的(添加一个元素时增加两个)......所以我更喜欢这个回复! :)
  • 这也适用于早期版本的 bash,在添加 += 之前,例如版本 2
  • 这也适用于您的元素中包含空格的情况 - $arr += ($el) 似乎将字符串按空格拆分并添加每个元素。
【解决方案5】:

使用索引数组,您可以这样做:

declare -a a=()
a+=('foo' 'bar')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-23
    • 1970-01-01
    • 2013-10-25
    • 2023-03-27
    • 2013-01-11
    • 2018-02-01
    相关资源
    最近更新 更多