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?
4 Answers
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:
- Get all elements before Index position2 arr[0] and arr[1];
- Add an element to the array;
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
Using
unset
(actually assign 'null' value to the element)unset -v 'arr[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[@]}"
del_element
in the removing example maybe should be better 0-based (index of first item=0 not 1). So betterarr=( "${arr[@]:0:$del_element}" "${arr[@]:$del_element+1}" )
.– TNTCommentedMar 4, 2022 at 11:35- When using regex, I think the value is replaced with a space rather than an empty string– SadmiCommentedMar 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.– αғsнιη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}– SadmiCommentedMar 17, 2023 at 16:29
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
- 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?– nhedCommentedSep 26, 2019 at 20:11
# 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 }
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")
ARRAY+=('foo')