110

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

144

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
    CommentedMar 4, 2022 at 11:35
  • When using regex, I think the value is replaced with a space rather than an empty string
    – Sadmi
    CommentedMar 17, 2023 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.CommentedMar 17, 2023 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
    CommentedMar 17, 2023 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
  • 4
    "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
    CommentedSep 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.

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.