A web development/programming blog providing info, tips, and tricks on programming languages, scripting, Linux, MySQL and more
How to append values to an array in bash
Last week I was working on a bash script for a project at work. The script parsed through a log file with server load and disk usage statistics at regular intervals. The script was calculating the average CPU idle time, disk utilization, and disk usage for servers. After calculating the averages for each of these three metrics, I then proceeded to loop through all the lines in the file and create an array of all the times when the CPU idle time was below average, or the disk utilization or usage was above average.
The code that I used was originally taken from the article Bash: Append to array using while-loop by Freddy Vulto. The concept that Freddy used is essentially the same as what I was doing. I was using a for loop to scan a file, and if certain values in the file met a condition, the date was added to an array which was printed at the end of the script execution. The code to achieve this is as follows:
array=( ${array[@]-} $(echo "$variable") )
The code above reads as follows:
array=( ….. ) : Set your array variable named, appropriately enough: array.
${array[@]-} : Read all variables from the array array. The hyphen at the end prevents an “unbound variable” error when -u or -o nounset is set and array is an empty array. This is useful for appending the first value to an empty array in the event that one of the aforementioned flags is set.
$(echo “$variable”) : Add the variable $variable to the array through the use of command substitution $(…) by reading the output of echo “$variable” as the input value for the array. The reason for command substitution is that if you try it without the $(…), bash will read echo and “$variable” as separate entries into the array instead of just the value of $variable


May 29, 2010 - 5:35 pm
Here is another, perhaps more efficient, way to do this:
array[${#array[*]}]=”$variable”
‘${#array[*]}’ yields the current number of items in the array. Which, when zero is your starting index, is the current end of the array. The syntax is kind of ugly but it works and does not make bash create a new array.
May 31, 2010 - 10:23 pm
@Joseph Coffland
Great tip Joseph. Syntax be damned, I’m always looking for ways to shorten my code. Thanks
June 30, 2010 - 3:00 pm
You guys are just making it too complicated.
Why not just use standard bash assignment operators, like +=?
#!/bin/bash
set -ue
IFS=”\t\n”
#create our empty list array
#synonymous to declare -a list
list=( )
#expand the list with a few values
list+=( ‘hello world!’ )
list+=( “foo” ‘bar’ 1 )
list+=( $((1+1)) “3″ ‘four’ `echo -e “65″`)
#print whole list, element at a time.
for i in “${list[@]}”
do
echo $i
done
# size of the list array should be 8
echo ${#list[@]}
unset list
June 30, 2010 - 3:17 pm
@Christof
I thought I tried that when I was working on this and I don’t recall it working. However, I just tried your example and it did work, so thank you. One question, is it dependent on the `set -ue` or `IFS=”\t\n”` line?
One note to those unfamiliar with the IFS variable, anytime you are working with it, I would recommend ALWAYS backing it up first and then setting it back at the end. You can cause some major issues by messing with IFS (Internal Field Separator) variable. I always set it as follows:
OLDIFS=$IFS
IFS=”\t\n”
…{code goes here}…
IFS=$OLDIFS
June 30, 2010 - 3:26 pm
That is easier.
’set -ue’ and ‘IFS=”\t\n”’ don’t seem to be required.
Is this somewhere in the bash documentation, because I couldn’t find it?
June 30, 2010 - 4:24 pm
set -ue is not required at all. I just add it to all my scripts for strict error checking.
I normally set IFS to $”\t\n” because spaces shouldn’t be separators, dammit ;)
but feel free to keep it at the default IFS=$” \t\n” if you’re willing to escape every space you deal with.
@Mark: In any case – IFS can be manipulated at will inside a script. Even inside a single function: local IFS=”". As long as you don’t do: export IFS=”somethingcrazy”, you should be fine.
@Joseph: uhm, i guess the += parameter should be discussed in the man page. Hmm, yup. Check http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameters
June 30, 2010 - 4:39 pm
@Christof
Thanks so much for the info. Very good to know. I always backup/restore the IFS as a safety net, but you’re right that as long as you don’t export, you’re fine. I wrote this post 4 months ago and was still relatively new to bash programming. I knew the language a bit, but had never done any programming. Thanks again.
June 30, 2010 - 4:43 pm
hey, it’s a pleasure. :)
if it weren’t for #!/ I’d not know a few things myself. So, thank you. :P
June 30, 2010 - 4:51 pm
Thank you :) I do what I can. Glad to know it’s helping out.