103

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

135

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")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.