Bash Array Operations: Length, Search, Slice, and Reverse

Once you know how to declare a Bash array, the next tasks are usually finding its length, checking whether it contains a value, extracting a slice, or changing the element order. Bash supports all of these operations, but the expansion syntax can be difficult to remember.
This guide covers the indexed-array operations you will use most often in scripts. For array declaration, element access, and associative arrays, start with the Bash arrays guide .
Sample Array
The examples use the following array:
fruits=("apple" "banana" "dragon fruit" "date" "elderberry")Each quoted value is one element, including dragon fruit, and the indices run from 0 through 4.
Get the Array Length
Use ${#name[@]} to get the number of elements:
echo "${#fruits[@]}"5The result is 5 because the array contains five elements. ${#name[*]} returns the same count, but @ is the safer default for other array operations because it preserves individual elements when quoted.
To get the character length of one element, include its index:
echo "${#fruits[1]}"6This counts the six characters in banana, not the number of array elements.
Check If an Array Contains a Value
Bash does not have a built-in contains operator. The reliable approach is to loop over the elements and compare each one with the target value:
contains() {
local target=$1
shift
local element
for element in "$@"; do
if [[ $element == "$target" ]]; then
return 0
fi
done
return 1
}
if contains "dragon fruit" "${fruits[@]}"; then
echo "found"
else
echo "not found"
fifoundThe function returns status 0 when it finds an exact match and status 1 otherwise. Passing "${fruits[@]}" keeps values containing spaces intact.
Avoid joining the array into one string and testing it with a regular expression. That shortcut can report false matches when a search term appears inside another element or when elements contain the chosen separator.
Slice an Array
Array slicing uses the following expansion:
${name[@]:offset:length}offset selects where the slice starts, and length is the number of elements to return. This example takes three elements starting at index 1:
slice=("${fruits[@]:1:3}")
printf '<%s>\n' "${slice[@]}"<banana>
<dragon fruit>
<date>Assigning the result to another array preserves the three values as separate elements.
A negative offset counts from the end. Add a space before the negative number so Bash does not parse :- as the default-value operator:
last_two=("${fruits[@]: -2}")
printf '<%s>\n' "${last_two[@]}"<date>
<elderberry>Omit length to take every remaining element from the offset to the end.
Reverse an Array
Bash does not provide a reverse operator. The following loop reads the array indices from the end and appends each value to a new array:
indices=("${!fruits[@]}")
reversed=()
for ((i=${#indices[@]} - 1; i >= 0; i--)); do
reversed+=("${fruits[${indices[i]}]}")
done
printf '<%s>\n' "${reversed[@]}"<elderberry>
<date>
<dragon fruit>
<banana>
<apple>Using the actual index list makes this pattern work with both contiguous arrays and sparse arrays that have gaps between indices.
Tools such as rev and tac solve different problems. rev reverses characters on each input line, while tac reverses line order. Neither one operates directly on Bash array elements.
Iterate Over Values and Indices
When you only need the values, expand the array with "${name[@]}":
for fruit in "${fruits[@]}"; do
echo "$fruit"
doneQuoting the expansion ensures that dragon fruit remains one loop item.
When you need both the index and value, use ${!name[@]} to expand the index list:
for i in "${!fruits[@]}"; do
echo "$i: ${fruits[i]}"
done0: apple
1: banana
2: dragon fruit
3: date
4: elderberryIterating over indices is useful when you need to update elements in place or preserve gaps in a sparse array.
Append and Prepend Elements
Append one or more elements with the += operator:
fruits+=("fig" "grape")The new values receive the next available indices at the end of the array.
To prepend a value, create a new array expansion with the new element first:
fruits=("apricot" "${fruits[@]}")This assignment rebuilds the array with contiguous indices starting at 0.
You can also assign a value at a specific index:
fruits[10]="kiwi"This creates a sparse array if indices 7 through 9 do not exist.
Remove Array Elements
Use unset with an index to remove one element:
unset 'fruits[2]'Quote the argument so the brackets are not treated as a filename pattern. The remaining elements keep their original indices, which leaves a gap where index 2 was removed.
To rebuild the array with contiguous indices, assign its current values back to it:
fruits=("${fruits[@]}")This preserves the values and renumbers them from 0.
To remove the entire array, pass only its name:
unset fruitsQuick Reference
For a printable quick reference, see the Bash cheatsheet .
| Task | Syntax |
|---|---|
| Number of elements | ${#arr[@]} |
| Length of one element | ${#arr[index]} |
| All values | "${arr[@]}" |
| All indices | "${!arr[@]}" |
| Slice | "${arr[@]:offset:length}" |
| Last two elements | "${arr[@]: -2}" |
| Append elements | arr+=(x y) |
| Prepend an element | arr=(x "${arr[@]}") |
| Set a specific index | arr[index]=value |
| Remove one element | unset 'arr[index]' |
| Reindex after removal | arr=("${arr[@]}") |
| Remove the array | unset arr |
Common Pitfalls
Always use curly braces when accessing an indexed element. $fruits[1] expands $fruits and then prints the literal text [1], while ${fruits[1]} expands the element at index 1.
Inside double quotes, "${fruits[@]}" expands each element as a separate word. "${fruits[*]}" joins all elements into one string using the first character of IFS. Use the @ form for loops, function arguments, copies, and most other array operations.
Do not assume that array indices are contiguous after using unset or assigning a distant index. Iterate over "${!fruits[@]}" when the actual index values matter.
Conclusion
Bash array expansions cover length checks, slices, index iteration, and most everyday updates. Use quoted @ expansions to preserve element boundaries, and iterate over the real index list when an array may contain gaps.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page