Remove element from bash array by content (stored in variable) without leaving a blank slot
If you want to delete the array element & shift the indices, you can use answer by l0b0 or JS웃.
However, if you don't want to shift the indices, you can use below script-let: (Particularly useful for associative arrays)
$ list=(one two three)
$ delete_me=two
$ for i in ${!list[@]};do
if [ "${list[$i]}" == "$delete_me" ]; then
unset list[$i]
fi
done
$ for i in ${!list[@]};do echo "$i = ${list[$i]}"; done
0 = one
2 = three
If you want to shift the indices to make them continuous, re-construct the array as this:
$ list=("${list[@]}")
$ for i in ${!list[@]};do echo "$i = ${list[$i]}"; done
0 = one
1 = three
You can delete an element from existing array though the whole process isn't very straightforward and may appear like a hack.
#!/bin/bash
list=( "one" "two" "three" "four" "five" )
var1="two"
var2="four"
printf "%s\n" "Before:"
for (( i=0; i<${#list[@]}; i++ )); do
printf "%s = %s\n" "$i" "${list[i]}";
done
for (( i=0; i<${#list[@]}; i++ )); do
if [[ ${list[i]} == $var1 || ${list[i]} == $var2 ]]; then
list=( "${list[@]:0:$i}" "${list[@]:$((i + 1))}" )
i=$((i - 1))
fi
done
printf "\n%s\n" "After:"
for (( i=0; i<${#list[@]}; i++ )); do
printf "%s = %s\n" "$i" "${list[i]}";
done
This script outputs:
Before:
0 = one
1 = two
2 = three
3 = four
4 = five
After:
0 = one
1 = three
2 = five
Key part of the script is:
list=( "${list[@]:0:$i}" "${list[@]:$((i + 1))}" )
Here we re-construct your existing array by specifying the index and length to remove the element from array completely and re-order the indices.
If you want to remove by value and shift the indexes I think you have to create a new array:
list=(one two three)
new_list=() # Not strictly necessary, but added for clarity
var="two"
for item in ${list[@]}
do
if [ "$item" != "$var" ]
then
new_list+=("$item")
fi
done
list=("${new_list[@]}")
unset new_list
Test:
$ echo "${list[@]}"
one three
$ echo "${#list[@]}"
2