106

I have an array containing some elements, but I want to push new items to the beginning of the array; How do I do that?

1

4 Answers 4

139

To add an element to the beginning of an array use.

arr=("new_element" "${arr[@]}")

Generally, you would do.

arr=("new_element1" "new_element2" "..." "new_elementN" "${arr[@]}")

To add an element to the end of an array use.

arr=( "${arr[@]}" "new_element" )

Or instead

arr+=( "new_element" )

Generally, you would do.

arr=( "${arr[@]}" "new_element1" "new_element2" "..." "new_elementN") #Or
arr+=( "new_element1" "new_element2" "..." "new_elementN" )

To add an element to specific index of an array use.

Let's say we want to add an element to the position of Index2 arr[2], we would actually do merge on below sub-arrays:

  1. Get all elements before Index position2 arr[0] and arr[1];
  2. Add an element to the array;
  3. Get all elements with Index position2 to the last arr[2], arr[3], ....

    arr=( "${arr[@]:0:2}" "new_element" "${arr[@]:2}" )
    

Removing an element from the array

In addition to removing an element from an array (let's say element #3), we need to concatenate two sub-arrays. The first sub-array will hold the elements before element #3 and the second sub-array will contain the elements after element #3.

arr=( "${arr[@]:0:2}" "${arr[@]:3}" )
  • ${arr[@]:0:2} will get two elements arr[0] and arr[1] starts from the beginning of the array.
  • ${arr[@]:3} will get all elements from index3 arr[3] to the last.

    one possible handy way to re-build the arr excluding element#3 (arr[2]) from that:

    del_element=3; arr=( "${arr[@]:0:$((del_element-1))}" "${arr[@]:$del_element}" )
    

    specify which element you want to exclude in del_element=.

Another possibility to remove an element is

  1. Using unset (actually assign 'null' value to the element)

    unset -v 'arr[2]'
    
  2. Use replace pattern if you know the value of your array elements to truncate their value (replace with empty string).

    arr=( "${arr[@]/PATTERN/}" )
    

Print the array

printf '%s\n' "${arr[@]}"
4
  • del_element in the removing example maybe should be better 0-based (index of first item=0 not 1). So better arr=( "${arr[@]:0:$del_element}" "${arr[@]:$del_element+1}" ).
    – TNT
    Mar 4, 2022 at 11:35
  • When using regex, I think the value is replaced with a space rather than an empty string
    – Sadmi
    Mar 17 at 13:18
  • @Sadmi here it's replacing with empty string, but if you wish to replace with space or other strings/characters you also can. Mar 17 at 13:27
  • Ok I got the reason, I was replacing in a string rather than the array I was using "${TESTS[@]/$del_element}" which is different from ${TESTS[@]/$del_element}
    – Sadmi
    Mar 17 at 16:29
6

Note that arrays in bash (copied from ksh) are rather associative arrays (with keys limited to positive integers also called sparse arrays).

a=(newvalue "$a[@]")

would make a new $a array with newvalue as ${a[0]} and the elements of the original array appended in the numerical order of their key with keys 1, 2...

For instance, if you had:

bash-4.4$ typeset -p a
declare -a a=([0]="foo" [12]="bar")
bash-4.4$ a=(newvalue "${a[@]}")
bash-4.4$ typeset -p a
declare -a a=([0]="newvalue" [1]="foo" [2]="bar")

That explains why there's no builtin operator for that.

If you wanted to insert the newvalue as ${a[0]} and shift all the other keys by one, you'd need a temporary array:

b=newvalue
for k in "${!a[@]}"; do
  b[k+1]=${a[k]}
done
unset a
for k in "${!b[@]}"; do
  a[k]=${b[k]}
done
unset b

Shells like zsh or yash that have normal arrays have operators for that:

  • zsh:

      a[1,0]=newvalue
    

(also works for prepending strings to scalar variables)

  • yash:

      array -i a 0 newvalue
    
1
  • 3
    "arrays in bash (copied from ksh) are rather associative arrays" ?? I thought there are "regular" (tho possibly sparse) and associative (where you can use strings as indecies) arrays in bash, what am I missing?
    – nhed
    Sep 26, 2019 at 20:11
2
# array declaration  
arr=()  

#Function to read data from file a and add into array  
fun_add_in_array()
{  
input=$1  
while IFS=',' read -r f1 f2  
do  
    echo "Element1 : $f1"  
    echo "Element2 : $f2"  
    arr+=( "$f1" )  
done < "$input"  
}  

#Function to print a array  
fun_read_array()  
{  
arr=("$@")  
for i in "${arr[@]}"  
do  
    echo $i  
done  
}
2

Create an Indexed Array:

$ declare -a A
$ declare -p A

declare -a A

Add some elements to the array:

$ A+=(foo)
$ A+=(bar)
$ A+=("baz quux")
$ declare -p A

declare -a A=([0]="foo" [1]="bar" [2]="baz quux")

Remove the middle element, making it a Sparse Indexed array:

$ unset A[1]
$ declare -p A

declare -a A=([0]="foo" [2]="baz quux")

Remove the last element from the Sparse Indexed Array:

$ unset A[-1]
$ declare -p A

declare -a A=([0]="foo")

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .