How to Delete an Element from a Shell Array
This post originally started as an exploration of the difference between * and @ in shell arrays. But as I wrote it, I realized the issue I had encountered wasn’t actually about * vs @ — it was a subtle problem with the way I was removing elements from an array. In this post, I’ll walk through how to delete an element from a shell array.
Delete by Index
Start with the following array:
1 | !/bin/bash |
To delete the second element (index 1):
1 | !/bin/bash |
Output:
1 | a c d a b c d |
Delete by Value
Sometimes you want to remove a specific value from the array — for example, remove all occurrences of b. The code is:
1 | !/bin/bash |
Result:
1 | a c d a c d |
Replacing * with @ in array1=( ${array1[*]/b} ) produces the same output.
Replacing ${array1[*]/b} with "${array1[*]/b}"
To better observe the behavior, add a loop to print each element of the array after removing b.
Code:
1 | !/bin/bash |
Result:
1 | a c d a c d |
Replacing @ with * in the for loop
The result is the same as above.
Changing the for loop to for value in "${array1[@]}" or for value in "${array1[*]}"
Code:
1 | !/bin/bash |
Result:
1 | a c d a c d |
Replacing ${array1[*]/b} with "${array1[@]/b}"
Code:
1 | !/bin/bash |
Result:
1 | a c d a c d |
Replacing @ with * in the for loop
The result is the same as above.
Changing the for loop to for value in "${array1[@]}"
Code:
1 | !/bin/bash |
Result:
1 | a c d a c d |
Changing the for loop to for value in "${array1[*]}"
Code:
1 | !/bin/bash |
Result:
1 | a c d a c d |
Delete Elements Containing a Substring
Using a different array for this test:
1 | !/bin/bash |
Result:
1 | cdf dfg |
This approach, like the ones above, is essentially string substitution/pattern matching.
The Difference Between * and @
These subscripts differ only when the word appears within double quotes. If the word is double-quoted, ${name[*]} expands to a single word with the value of each array member separated by the first character of the IFS variable, and ${name[@]} expands each element of name to a separate word.