Jay Taylor's notes

back to listing index

Bash: add value to array without specifying a key - Stack Overflow

[web search]
Original source (stackoverflow.com)
Tags: stackoverflow.com
Clipped on: 2013-02-08

Is there a way to do something like PHPs $array[] = 'foo'; in bash vs doing:

array[0] = 'foo'
array[1] = 'bar'
asked Dec 23 '09 at 8:59
Image (Asset 1/7) alt= 21.7k38105177
add comment

5 Answers

up vote 62 down vote accepted

Yes there is:

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

Bash Reference Manual:

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.

answered Dec 23 '09 at 9:02
Image (Asset 2/7) alt= 2,061919
  upvote
 flag
hmm, does not seem supported by bash v 4.1.x, answer of @ghostdog74 is neat for this version though – akostadinov Sep 14 '12 at 19:29
  upvote
 flag
This works just fine with bash 3.2.48 (OS X 10.8.2). Note that ARRAY is just a placeholder for an actual variable name. Even if your array indices are not sequential, appending with += will simply assign to the highest index + 1. – mklement Sep 21 '12 at 3:01
  upvote
 flag
Is there something like that in bash version 4.2.24(1)? – Ali Ismayilov Dec 1 '12 at 12:51
add comment

From the bash documentation:

Arrays are assigned to using compound assignments of the form

 name=(value1 ... valueN)

where each VALUE is of the form [[SUBSCRIPT]=]STRING. If the optional subscript is supplied, that index is assigned to; otherwise the index of the element assigned is the last index assigned to by the statement plus one. Indexing starts at zero. This syntax is also accepted by the declare builtin. Individual array elements may be assigned to using the name['SUBSCRIPT']=VALUE syntax introduced above.

answered Dec 23 '09 at 9:03
Image (Asset 3/7) alt= 100k15116236
5 upvote
 flag
I can't understand a word of that… – andrewdotnich Mar 25 '11 at 1:01
add comment

If you array is always sequential and starts at 0, then you can do this:

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

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

Image (Asset 4/7) alt= 5,75842554
answered Dec 23 '09 at 9:03
Image (Asset 5/7) alt= 1,357410
  upvote
 flag
Yes, you can, but the += syntax (see @e-t172's answer) is (a) simpler, and (b) also works with arrays that are non-contiguous and/or do not start with 0. – mklement Sep 21 '12 at 3:06
add comment
$ declare -a arr
$ arr=("a")
$ arr=(${arr[@]} "new")
$ echo ${arr[@]}
a new
$ arr=(${arr[@]} "newest")
$ echo ${arr[@]}
a new newest
answered Dec 23 '09 at 9:11
Image (Asset 6/7) alt= 55.2k54790
1 upvote
 flag
nice for bash versions that do not support the semantics of += operator explained by e-t172 – akostadinov Sep 14 '12 at 19:26
add comment

As Dumb Guy points out, it's important to note whether the array starts at zero and is sequential. Since you can make assignments to and unset non-contiguous indices ${#array[@]} is not always the next item at the end of the 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

Here's how to get the last index:

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

That illustrates how to get the last element of an array. You'll often see this:

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

As you can see, because we're dealing with a sparse array, this isn't the last element. This works on both sparse and contiguous arrays, though:

$ echo ${array[@]: -1}
i
answered Dec 23 '09 at 10:38
Image (Asset 7/7) alt= 65.2k760111
1 upvote
 flag
Great stuff; never knew that substring-extraction syntax could be applied to arrays too; the rules, determined by trial and error, are (bash 3.2.48): ${array[@]: start[:count]} Returns count elems. or, if not specified, all remaining elems. starting at the following elem.: - If start >= 0: from the elem. whose index is >= start. - If start < 0: from the elem. whose index is (last array index + 1) - abs(start); CAVEAT: if abs(start) > (last array index + 1), a null string is returned. If count is specified, as many elements are returned, even if their indices are not contiguous from start. – mklement Sep 21 '12 at 5:47
1 upvote
 flag
@mklement: In Bash 4.2, you can use negative array subscripts to access elements counting from the end of the array. ${array[-1]} – Dennis Williamson Sep 21 '12 at 15:02
  upvote
 flag
That's good to know, thanks. OS X (as of 10.8.2) still uses 3.2.48, and stackoverflow.com/questions/10418616/… tells me that, unfortunately, "Apple use quite an old version of Bash, as they don't ship code that's licensed under GPL3." – mklement Sep 21 '12 at 15:29