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') |