shell programming - arrays

created onJanuary 18, 2022

welcome to the world of negative indices and other barnyard oddities.

initializing an array

arr=() initialize an empty array arr=(1 2 3) initialize an array with values

initializing an array from command output

arr=$(ls) initialize an array from the output of 'ls'

setting elements of an array

indices inside bounds

array values are treated as strings. if the index is omitted, index 0 is assumed.

arr=(1 2 3) initialize array arr+=9 array is now 19 2 3 arr[2]+=0 array is now 19 2 30 arr[1]=(1 2) results in error 'bash: arr[1]: cannot assign list to array member'

indices out of bounds

specifying an positive index that is out of the bounds of the array increases the array size instead of throwing an error

arr=(1 2 3) initialize array arr[4]=4 array is now 1 2 3 4, index size is 4, index values are 0 1 2 4

negative indices

negative values for indices are, counterintuitively again, applied in a ‘wrap around’ manner. specifying an index of -1 sets or retrieves the last element of an array. no modulo calculation is applied. thus, specifying an index of -5 for an array with three elements results in an error (bash: arr[-5]: bad array subscript)

arr=(1 2 3) array is now 1 2 3 arr[-1]=9 array is now 1 2 9 arr[-5]=8 results in error 'bash: arr[-5]: bad array subscript' arr[-3]=8 array is now 8 2 9

concatenating arrays

arr=(1 2 3) array is now 1 2 3 arr+=(4 5) concatenating, short form, array is now 1 2 3 4 5 arr=(${arr[@]} 6 7) concatenating, long form, array is now 1 2 3 4 5 6 7 what=(1 2 3) ever=(a b c) whatever=("${what[@]}" "${ever[@]}") whatever is (1 2 3 a b c)

getting information about an array

retrieve array values

${arr[@]} retrieve array values

retrieve array indices

${!arr[@]} retrieve array indices

retrieve array size

${#arr[@]} retrieve array size

retrieve length and parts of an element

${#arr[3]} length of the element located at index 3 arr=(blueberries cranberries) ${arr[0]:0:4} returns 'blue'

iterating over arrays

retrieving all values of an array in a single string

fruit=(apples bananas cherries cranberries) printf "%s\n" "${fruit[*]}"

output of the command above is

apples bananas cherries cranberries

retrieving all values of an array, one at a time

fruit=(apples bananas cherries cranberries) printf "%s\n" "${fruit[@]}"

output of the command above is

apples bananas cherries cranberries

retrieve n elements, starting at index i

fruit=(apples bananas cherries cranberries) array fruit is apples bananas cherries cranberries selectedFruit=${arr[@]:1:2} array selectedFruit is bananas cherries

retrieving all elements of an array and simultaneously replacing elements of an array

fruit=(apples cranberries bananas cherries cranberries) array fruit is apples bananas cherries cranberries changedFruit=${fruit[@]/cran/blue} array changedFruit is apples blueberries bananas cherries blueberries

the replacement shouldn’t be done on the original array, as this will lead to strange results

fruit=(apples bananas cherries cranberries) fruit=${fruit[@]/cran/blue} printf "%s\n" ${fruit[@]}

the code above generates the following output

apples bananas cherries blueberries bananas cherries cranberries

retrieving all elements of an array, simultaneously dicarding elements matching a certain pattern

fruit=(apples bananas cherries cranberries) array fruit is apples bananas cherries cranberries retrievedFruit=${fruit[@]/cran*/} array retrievedFruit is apples bananas cherries

again, the retrieved elements minus the discarded elements should not be stored (back) to the original array, as this will lead (again) to strange results. the code below

fruit=(apples bananas cherries cranberries) array fruit is apples bananas cherries cranberries fruit=${fruit[@]/cran*/} printf "%s\n" ${fruit[@]}

results in the following output

apples bananas cherries bananas cherries cranberries

deleting arrays and elements of an array

deleting an entire array

arr=(1 2 3) array arr is 1 2 3 unset arr deletes array arr

deleting elements of an array

arr=(1 2 3) array arr is 1 2 3 unset arr[1] array arr is 1 3, array indices are 0 2, array size is 2
arr=(1 2 3 4) index=2 arr=(${arr[@]:0:$index} ${arr[@]:$(($index + 1))}) array arr is now 1 2 4, array indices are 0 1 2, array size is 3