Add a new element to an array without specifying the index in Bash
有没有办法在bash中执行类似PHPs $array[] = 'foo';的操作:
1 2
   | array[0] = 'foo' 
array[1] = 'bar'  | 
 
就在这里:
1 2 3
   | ARRAY=() 
ARRAY+=('foo') 
ARRAY+=('bar')  | 
 
Bash参考手册:
In the context where an assignment statement is assigning a value to a shell variable or array index (see Arrays), the ‘+=’ operator can be used to append to or add to the variable's previous value.
		
		
- 
这适用于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版本中。
 
- 
此外,ARRAY=("${ARRAY[@]}""new value" )有效。但是如果数组为空并且你设置了set -u,那就很糟糕了。请注意,如果数组为空,则此语法不会添加空元素。因此,这种语法将有助于旧版本
 
- 
就像TheConstructor所说的那样,也不要把ARRAY + =('foo')与"让ARRAY + =('foo')"混淆,这只会将第一项(foo)视为0的整数,并将第一个索引转换为整数输入(-i),并添加值(除非你传递了一个已声明的变量(即声明-i foo = 4),否则该值将被添加,即使你没有放入自'let'计算后的$ on就像$(())一样。
 
- 
为什么它不适合我? :~/tmp$ myarray=(jj) :~/tmp$ echo $myarray jj :~/tmp$ myarray+=(hh) :~/tmp$ echo $myarray jj 
 
- 
@TheConstructor:好点;当你执行ARRAY+='foo'时,它始终是index 0,无论数组的真正最低索引是什么。
 
- 
@Jas:要访问整个数组,必须使用${myarray[@]} - 引用一个数组变量,就好像它是一个标量与访问它的元素0相同;换句话说:$myarray与${myarray[0]}相同。
 
- 
@socketpair ARRAY=("${ARRAY[@]}""new value" )将索引重新编号为ARRAY内的元素。这是稀疏ARRAY的问题。
 
- 
对于任何试图将命令输出添加到数组的人,请不要使用ARRAY+=$(),而是使用变量来保存命令的输出,然后将其添加到数组VAR="$()"; ARRAY+=("$VAR")。在Bash 4及更高版本mapfile中也可以使用,请参阅@ gniourf_gniourf的答案。
 
- 
@Vito ARRAY+=( $(command) )本来没问题。 readarray / mapfile当然要灵活得多
 
- 
@AliIsmayilov和其他任何不适用的人,请确保您没有在子shell中添加项目。
 
- 
是否可以一次添加多个元素?例如,ARRAY+=('foo' 'bar')或ARRAY+=('foo bar')?
 
- 
@MikeShiyan是的,ARRAY+=('foo' 'bar')将起作用并将添加项目'foo'和'bar'。 ARRAY+=('foo bar')将添加单个项目'foo bar'。
 
 
	  
正如Dumb Guy指出的那样,重要的是要注意阵列是否从零开始并且是顺序的。 由于您可以分配和取消设置非连续索引,因此${#array[@]}并不总是数组末尾的下一个项目。
1 2 3 4 5 6 7 8 9 10
   | $ 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  | 
 
以下是获取最后一个索引的方法:
1 2 3 4
   | $ end=(${!array[@]})   # put all the indices in an array 
$ end=${end[@]: -1}    # get the last one 
$ echo $end 
42  | 
 
这说明了如何获取数组的最后一个元素。 你会经常看到这个:
1 2
   | $ echo ${array[${#array[@]} - 1]} 
g  | 
 
如您所见,因为我们正在处理稀疏数组,所以这不是最后一个元素。 这适用于稀疏和连续数组,但是:
1 2
   | $ echo ${array[@]: -1} 
i  | 
 
		
		
- 
好东西; 从来不知道子串提取语法也可以应用于数组; 通过反复试验确定的规则是(bash 3.2.48):${array[@]: start[:count]}返回计数elems。 或者,如果没有说明,所有剩余的元素。 从以下元素开始: - 如果start> = 0:从elem开始。 其索引是> = start。 - 如果从elem开始<0: 其索引是(最后一个数组索引+ 1) - abs(start); CAVEAT:如果abs(start)>(最后一个数组索引+ 1),则返回一个空字符串。 如果指定了count,则返回许多元素,即使它们的索引从start开始也不连续。
 
- 
@mklement:在Bash 4.2中,您可以使用负数组下标来访问从数组末尾开始计数的元素。${array[-1]}
 
- 
很高兴知道,谢谢。 OS X(截至10.8.2)仍然使用3.2.48和stackoverflow.com/questions/10418616/… 告诉我,不幸的是,"Apple使用相当旧版本的Bash,因为它们不提供根据GPL3许可的代码。"
 
 
	  
 
1 2 3 4 5 6 7 8
   | $ 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")
 
- 
这也可以用于推送阵列前面,这正是我需要的。
 
 
	  
如果您的数组始终是顺序的并且从0开始,则可以执行以下操作:
1 2 3 4
   | array[${#array[@]}]='foo' 
 
# gets the length of the array 
${#array_name[@]}  | 
 
如果你无意中在等号之间使用了空格:
1
   | array[${#array[@]}] = 'foo'  | 
 
然后你会收到类似于的错误:
1
   | array_name[3]: command not found  | 
 
		
		
- 
是的,你可以,但+=语法(参见@ e-t172的答案)是(a)更简单,(b)也适用于非连续和/或不以0开头的数组。
 
- 
老实说,这个解决方案(对我而言)比"+ ="效果更好,因为后者的长度有时是错误的(添加一个元素时增加2个)...所以我更喜欢这个回复! :)
 
- 
在添加+=之前,这也适用于早期版本的bash,例如版本2
 
 
	  
使用索引数组,您可以这样:
1 2
   | declare -a a=() 
a+=('foo' 'bar')  |