Add a new element to an array without specifying the index in Bash

BashArrays

Bash Problem Overview


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

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

Bash Solutions


Solution 1 - Bash

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.

Also: > When += is applied to an array variable using compound assignment (see Arrays below), the variable's value is not unset (as it is when using =), and new values are appended to the array beginning at one greater than the array's maximum index (for indexed arrays)

Solution 2 - Bash

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

Solution 3 - Bash

$ declare -a arr
$ arr=("a")
$ arr=("${arr[@]}" "new")
$ echo ${arr[@]}
a new
$ arr=("${arr[@]}" "newest")
$ echo ${arr[@]}
a new newest

Solution 4 - Bash

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

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

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

If you inadvertently use spaces between the equal sign:

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

Then you will receive an error similar to:

array_name[3]: command not found

Solution 5 - Bash

With an indexed array, you can to something like this:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDarryl HeinView Question on Stackoverflow
Solution 1 - BashEtienne DechampsView Answer on Stackoverflow
Solution 2 - BashDennis WilliamsonView Answer on Stackoverflow
Solution 3 - Bashghostdog74View Answer on Stackoverflow
Solution 4 - BashDumb GuyView Answer on Stackoverflow
Solution 5 - BashGrégory RocheView Answer on Stackoverflow