Looping Over Array Elements
In this page:
Iterating Values Directly
for val in "${arr[@]}"; do ... done gives you each array element in turn, fully preserved even if an element contains spaces, as long as you quote the expansion. This is the most common and straightforward way to process every item in an array.
Example: Iterating Values Directly
#!/bin/bash
fruits=("apple" "kiwi fruit" "cherry")
for fruit in "${fruits[@]}"; do
echo "Fruit: $fruit"
done
Login to try C/C++/Java/PHP code in the editor
Iterating Indices with ${!arr[@]}
"${!arr[@]}" expands to the list of indices currently present in the array (not the values), which is useful when you need to know each element's position, especially since Bash arrays can have gaps. You then look up each value with ${arr[idx]} inside the loop.
Example: Iterating Indices with ${!arr[@]}
#!/bin/bash
fruits=("apple" "banana" "cherry")
for idx in "${!fruits[@]}"; do
echo "Index $idx: ${fruits[idx]}"
done
Login to try C/C++/Java/PHP code in the editor
Why Quoting the Expansion Matters
Leaving ${arr[@]} unquoted lets word splitting break any element containing spaces into multiple separate loop iterations, silently corrupting your data. Quoting it as "${arr[@]}" guarantees each element is treated as exactly one item, regardless of its contents.
Example: Why Quoting the Expansion Matters
#!/bin/bash
items=("first item" "second item")
echo "Unquoted (broken):"
for i in ${items[@]}; do
echo " [$i]"
done
echo "Quoted (correct):"
for i in "${items[@]}"; do
echo " [$i]"
done
Login to try C/C++/Java/PHP code in the editor
C-Style Loop Over Array Length
A numeric C-style for loop can also walk an array by index, counting from 0 up to (but not including) ${#arr[@]}, the array's element count. This approach is handy when you specifically need to compare or modify neighboring indices, not just read values in order.
Example: C-Style Loop Over Array Length
#!/bin/bash
colors=(red green blue)
for (( i = 0; i < ${#colors[@]}; i++ )); do
echo "colors[$i] = ${colors[i]}"
done
Login to try C/C++/Java/PHP code in the editor
- Forgetting to quote
${arr[@]}as"${arr[@]}", which loses the protection for elements that contain spaces and causes them to be split into multiple words. - Using
${arr[*]}when you meant${arr[@]}inside a loop;[*]joins everything into a single string (subject toIFS), so aforloop over it (quoted) would only see one combined item instead of iterating each element. - Assuming array indices are always sequential when looping with
${!arr[@]}; if elements were removed withunset, gaps can exist, so index-based loops should not assume every number from 0 to length-1 exists.
for val in "${arr[@]}"iterates over each array element as a separate, fully preserved value.for idx in "${!arr[@]}"iterates over the array's indices (the!prefix requests indices, not values).- Combine both when you need index and value together: loop over
"${!arr[@]}"and look up${arr[idx]}. - Always quote
"${arr[@]}"/"${!arr[@]}"in loops to keep elements with spaces intact.
Chapter Quiz — Complete all 14 topics to unlock
0/14 topics done
Complete these topics first: