向数组添加新元素,而不在Bash中指定索引

Dar*_*ein 734 arrays bash

有没有办法$array[] = 'foo';在bash中执行类似PHP的操作:

array[0] = 'foo'
array[1] = 'bar'
Run Code Online (Sandbox Code Playgroud)

Eti*_*mps 1429

就在这里:

ARRAY=()
ARRAY+=('foo')
ARRAY+=('bar')
Run Code Online (Sandbox Code Playgroud)

Bash参考手册:

在赋值语句为shell变量或数组索引赋值的上下文中(参见Arrays),'+ ='运算符可用于追加或添加到变量的先前值.

  • 值得注意的是,ARRAY + =('foo')与ARRAY + ='foo'不同,它将字符串'foo'附加到具有最低(?)键的条目. (187认同)
  • @Jas:要访问_entire_数组,必须使用`$ {myarray [@]}` - 引用数组变量,就像它是标量一样,与访问其元素0相同; 换句话说:`$ myarray`与`$ {myarray [0]}`相同. (37认同)
  • 这适用于bash 3.2.48(OS X 10.8.2).请注意,`ARRAY`只是实际变量名称的占位符.即使你的数组​​索引是_not_ sequential,附加`+ =`也只会分配给最高的索引+ 1. (21认同)
  • 根据http://wiki.bash-hackers.org/scripting/bashchanges,此语法首次出现在3.1-alpha1版本中. (8认同)
  • 在bash版本4.2.24(1)中有类似的东西吗? (3认同)
  • 此外,`ARRAY =("$ {ARRAY [@]}""新值")`有效.但是如果数组为空并且你设置了'set -u`就很糟糕.请注意,如果数组为空,则此语法不会添加空元素.因此,这种语法将有助于旧版本 (3认同)
  • 为什么它不适合我?`:~/tmp$ myarray=(jj) :~/tmp$ echo $myarray jj :~/tmp$ myarray+=(hh) :~/tmp$ echo $myarray jj ` (3认同)
  • @socketpair`ARRAY =("$ {ARRAY [@]}""新值")`将索引重新编号为`ARRAY`中的元素.那个*是稀疏`ARRAY'的问题. (3认同)
  • @Vito`ARRAY + =($(命令))`本来没问题.`readarray` /`mapfile`当然要灵活得多 (3认同)
  • @TheConstructor:好点; 无论数组的真正最低指数是什么,当你执行`ARRAY + ='foo'时,它都是_always_ index`0`. (2认同)
  • 对于任何试图将命令输出添加到数组的人,请勿使用`ARRAY + = $(<command>)`,而应使用变量保存命令的输出,然后将其添加到数组`VAR =“ $(<命令>)“; ARRAY + =(“ $ VAR”)`。在Bash 4和更高版本中,也可以使用“ mapfile”,请参见@gniourf_gniourf的答案[here](http://stackoverflow.com/a/32931403/2121777)。 (2认同)
  • @AliIsmayilov 和其他任何人这不起作用,请确保您没有[在子shell中添加项目](/sf/ask/1588400551/在bash中)。 (2认同)
  • @MikeShiyan是的,`ARRAY + =('foo''bar')`将起作用,并将添加项目''foo'`和''bar'`。`ARRAY + =('foo bar')`将添加单个项目''foo bar'`。 (2认同)

Pau*_*ce. 74

正如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
Run Code Online (Sandbox Code Playgroud)

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

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

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

$ echo ${array[${#array[@]} - 1]}
g
Run Code Online (Sandbox Code Playgroud)

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

$ echo ${array[@]: -1}
i
Run Code Online (Sandbox Code Playgroud)

  • 好东西; 从来不知道子串提取语法也可以应用于数组; 通过反复试验确定的规则是(bash 3.2.48):`$ {array [@]:start [:count]}`返回计数elems.或者,如果没有指定,则所有_remaining_ elems.从以下元素开始: - 如果start> = 0:从elem开始.其索引是> = start. - 如果从elem开始<0:其索引是(最后一个数组索引+ 1) - abs(start); CAVEAT:如果abs(start)>(最后一个数组索引+ 1),则返回一个空字符串.如果指定了count,则返回许多元素,即使它们的索引从start开始也不连续. (3认同)
  • @mklement:在Bash 4.2中,您可以使用负数组下标来访问从数组末尾开始计数的元素.`$ {阵列[-1]}` (3认同)

gho*_*g74 48

$ declare -a arr
$ arr=("a")
$ arr=("${arr[@]}" "new")
$ echo ${arr[@]}
a new
$ arr=("${arr[@]}" "newest")
$ echo ${arr[@]}
a new newest
Run Code Online (Sandbox Code Playgroud)

  • 一个好的向后兼容的解决方案,但要注意,如果任何现有元素中有空格,它们将被分成多个元素; 使用`arr =("$ {arr [@]}""new")`如果你的元素中有空格 (12认同)
  • 适用于不支持e-t172解释的+ =运算符语义的bash版本 (8认同)
  • 这也可以用来推到数组前面,这正是我所需要的。 (2认同)

Dum*_*Guy 25

如果您的数组始终是顺序的并且从0开始,则可以执行以下操作:

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

# gets the length of the array
${#array_name[@]}
Run Code Online (Sandbox Code Playgroud)

如果你无意中在等号之间使用了空格:

array[${#array[@]}] = 'foo'
Run Code Online (Sandbox Code Playgroud)

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

array_name[3]: command not found
Run Code Online (Sandbox Code Playgroud)

  • 是的,你可以,但是`+ =`语法(参见@ e-t172的答案)是(a)更简单,(b)也适用于非连续和/或不以0开头的数组. (5认同)

Gré*_*che 6

使用索引数组,您可以执行以下操作:

declare -a a=()
a+=('foo' 'bar')
Run Code Online (Sandbox Code Playgroud)