Mutable list or array structure in Bash? How can I easily append to it?

ArraysBashScripting

Arrays Problem Overview


I'm trying to collect string values in a bash script. What's the simplest way that I can append string values to a list or array structure such that I can echo them out at the end?

Arrays Solutions


Solution 1 - Arrays

$ arr=(1 2 3)
$ arr+=(4)
$ echo ${arr[@]}
1 2 3 4

Since Bash uses sparse arrays, you shouldn't use the element count ${#arr} as an index. You can however, get an array of indices like this:

$ indices=(${!arr[@]})

Solution 2 - Arrays

foo=(a b c)
foo=("${foo[@]}" d)
for i in "${foo[@]}"; do echo "$i" ; done

Solution 3 - Arrays

To add to what Ignacio has suggested in another answer:

foo=(a b c)
foo=("${foo[@]}" d) # push element 'd'

foo[${#foo[*]}]="e" # push element 'e'

for i in "${foo[@]}"; do echo "$i" ; done

Solution 4 - Arrays

$ for i in "string1" "string2" "string3"
> do
> array+=($i)
> done
$ echo ${array[@]}
string1 string2 string3

Solution 5 - Arrays

The rather obscure syntax for appending to the end of an array in Bash is illustrated by the following example:

myarr[${#myarr[*]}]="$newitem"

Solution 6 - Arrays

Though the question is answered and is pretty old, I'd like to share a namespace-solution as it works significantly faster than any other ways except for ennukiller's answer (on my 100k lines tests it won ~12 secs against my ~14 secs, whereas list-append solution would take a few minutes).

You can use the following trick:

# WORKS FASTER THAN THESE LAME LISTS! ! !
size=0;while IFS= read -r line; do
	echo $line
	((++size))
	eval "SWAMP_$size='$line'"
done

Or you can do the following:

#!/bin/bash
size=0
namespace="SWAMP"

ArrayAppend() {
	namespace="$1"
	# suppose array size is global
	new_value="$2"
	eval "${namespace}_$size='$2'"
	eval "echo \$${namespace}_$size"
    ((++size))
}

ArrayAppend "$namespace" "$RANDOM"
ArrayAppend "$namespace" "$RANDOM"
ArrayAppend "$namespace" "$RANDOM"
ArrayAppend "$namespace" "$RANDOM"
ArrayAppend "$namespace" "$RANDOM"

As long as the interpreter is in tag list, here's a link for object oriented bash.

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
QuestionJoeView Question on Stackoverflow
Solution 1 - ArraysDennis WilliamsonView Answer on Stackoverflow
Solution 2 - ArraysIgnacio Vazquez-AbramsView Answer on Stackoverflow
Solution 3 - ArrayscodaddictView Answer on Stackoverflow
Solution 4 - Arraysghostdog74View Answer on Stackoverflow
Solution 5 - ArraysennuikillerView Answer on Stackoverflow
Solution 6 - Arraystheoden8View Answer on Stackoverflow