How to Loop with Index
Quick Answer: Loop with Array Index in Bash
Use a C-style for loop to iterate with indices: for ((i=0; i<${#array[@]}; i++)); do echo "${array[$i]}"; done. This gives you both the index number and array value. Use index loops when you need position-based processing or numbering.
Quick Comparison: Loop Methods with Index
| Method | Syntax | Index Available | Best For |
|---|---|---|---|
| C-style for | for ((i=0; i<N; i++)) | Yes ($i) | Indices, modification |
| while loop | while (( i < N )); do | Yes ($i) | Custom control |
| for-in loop | for item in "${arr[@]}" | No | Simple iteration |
| Index function | find_index value array | Yes (returned) | Finding positions |
Bottom line: Use C-style for ((i=0; i<N; i++)) when you need indices. Use for item in array when you just need values.
Looping with Array Indices
Sometimes you need both the index position and the value from an array. This is useful for numbered output, conditional processing based on position, or updating specific array elements. Bash provides several ways to loop with indices.
C-Style Loop with Indices
The most straightforward approach:
#!/bin/bash
fruits=("apple" "banana" "cherry" "date")
# Loop through array with index
for ((i=0; i<${#fruits[@]}; i++)); do
echo "$i: ${fruits[$i]}"
done
Output:
0: apple
1: banana
2: cherry
3: date
When to Use C-Style Index Loops
- You need to display line numbers (1, 2, 3…)
- You want to show progress ([1/10], [2/10]…)
- You need to update array values by index
- You want to skip certain positions
Practical Examples
Numbered List
#!/bin/bash
items=("First task" "Second task" "Third task")
echo "To-Do List:"
for ((i=0; i<${#items[@]}; i++)); do
echo "$((i+1)). ${items[$i]}"
done
Output:
To-Do List:
1. First task
2. Second task
3. Third task
Understanding C-Style Loop Syntax
Breaking down the index loop:
((i=0))- Initialize counter at 0i<${#fruits[@]}- Loop while counter is less than array length((i++))- Increment counter after each iteration${fruits[$i]}- Access array element at index
Process Files with Status
```bash
#!/bin/bash
files=("file1.txt" "file2.txt" "file3.txt")
echo "Processing files..."
for ((i=0; i<${#files[@]}; i++)); do
total=${#files[@]}
current=$((i+1))
echo "[$current/$total] Processing: ${files[$i]}"
# Do work on file...
done
Output:
Processing files...
[1/3] Processing: file1.txt
[2/3] Processing: file2.txt
[3/3] Processing: file3.txt
When to Use Progress Status
- You’re processing multiple files
- You want users to see progress
- You need to track which file you’re on
- You want to show completion percentage
Using Index for Conditional Processing
Take different actions based on position:
#!/bin/bash
commands=("init" "start" "build" "deploy")
for ((i=0; i<${#commands[@]}; i++)); do
if (( i == 0 )); then
echo "[$i] FIRST: ${commands[$i]} (critical)"
elif (( i == ${#commands[@]} - 1 )); then
echo "[$i] LAST: ${commands[$i]} (final step)"
else
echo "[$i] MID: ${commands[$i]}"
fi
done
When to Use Conditional Processing
- You handle the first item differently
- You handle the last item differently
- You need special processing for middle items
- You’re building a sequence with different steps
Updating Array Elements by Index
Modify values as you iterate:
#!/bin/bash
numbers=(1 2 3 4 5)
# Double each number
for ((i=0; i<${#numbers[@]}; i++)); do
numbers[$i]=$((numbers[$i] * 2))
done
echo "Doubled: ${numbers[@]}"
# Output: Doubled: 2 4 6 8 10
When to Use Array Modification
- You need to transform all values
- You’re applying a formula to each element
- You want to normalize or scale data
- You’re building a new version of the array
Skipping Elements by Index
Use conditionals to skip specific positions:
#!/bin/bash
data=("keep" "skip" "keep" "skip" "keep")
for ((i=0; i<${#data[@]}; i++)); do
# Skip even indices
(( i % 2 == 0 )) && echo "[$i] ${data[$i]}"
done
Output:
[0] keep
[2] keep
[4] keep
When to Use Index Skipping
- You need every other element
- You want only specific positions
- You’re filtering by position
- You’re sampling data
Process Command Output with Index
#!/bin/bash
# Get list of processes
mapfile -t processes < <(ps aux | tail -n +2 | awk '{print $11}')
echo "Process list with index:"
for ((i=0; i<${#processes[@]}; i++)); do
# Only show first 5
(( i >= 5 )) && break
echo "$((i+1)). ${processes[$i]}"
done
When to Use Process Output Pattern
- You’re working with
ps,ls, or similar commands - You want to process limited results
- You need index-based selection from command output
- You’re building a list from system commands
Two-Dimensional Array Processing
#!/bin/bash
# Simulate 2D array
grid=(
"1 2 3"
"4 5 6"
"7 8 9"
)
echo "Grid with indices:"
for ((i=0; i<${#grid[@]}; i++)); do
echo "Row $i: ${grid[$i]}"
done
When to Use 2D Arrays
- You have grid-like data
- You’re processing rows
- You’re building a matrix structure
- You want to organize hierarchical data
Finding Array Index of Value
Locate where a value is stored:
#!/bin/bash
colors=("red" "green" "blue" "yellow" "red")
find_index() {
local search="$1"
shift
local array=("$@")
for ((i=0; i<${#array[@]}; i++)); do
if [ "${array[$i]}" = "$search" ]; then
echo "$i"
return 0
fi
done
echo "-1" # Not found
return 1
}
idx=$(find_index "blue" "${colors[@]}")
echo "Index of 'blue': $idx"
# Output: Index of 'blue': 2
When to Use Index Finding
- You need to locate a value in an array
- You want to know the position of an item
- You’re searching for the first/last occurrence
- You’re implementing search functionality
Quick Reference
# Get array length
${#array[@]}
# Loop with index
for ((i=0; i<${#array[@]}; i++)); do
echo "[$i]: ${array[$i]}"
done
# First element
${array[0]}
# Last element
${array[-1]}
# All elements
${array[@]}
Summary
Looping with array indices is powerful for numbered output, conditional processing, and updating values. The C-style for ((i=0; i<N; i++)) loop is the most common and efficient approach in Bash. Use index loops when you need position information, when you’re modifying values, or when you need to handle first/last elements differently.