Skip to content
Go back

Bash for loops sequential counting

Updated:
By SumGuy 4 min read
Bash for loops sequential counting

Bash loops are one of those foundational tools you reach for constantly. Need to process files in bulk? Retry something with backoff? Rename 50 photos with sequential numbers? A solid loop is your best friend. Let’s cover the most practical patterns you’ll actually use, from simple ranges to stepping, zero-padding, and real-world scenarios.

The Classic Range Loop

Start simple. Count from 1 to 100:

basic-range.sh
for i in {1..100}; do
echo $i
done

That brace expansion {1..100} is pure Bash and super efficient. Add a timestamp to each output:

range-with-timestamp.sh
for i in {1..100}; do
echo "$(date +"%D %I:%M:%S") - $i"
done

Stepping Through a Range

Every 3rd number instead of every 1:

stepping.sh
for i in {1..100..3}; do
echo "$(date +"%D %I:%M:%S") - $i"
done

The third parameter is the step size. Want every 5th? Use {1..100..5}.

The seq Command

Before brace expansion, there was seq. It’s handy for dynamic ranges:

seq-dynamic.sh
# Count from 1 to 100
seq 1 100
# Every 2nd number
seq 1 2 100
# Backwards
seq 100 -1 1
# Zero-padded output (useful for filenames)
seq -w 1 100

With seq -w, you get 001, 002, 003...100 instead of 1, 2, 3...100. That’s huge for file sorting.

C-Style for Loops

If you need more control, go C-style:

c-style.sh
for ((i=1; i<=100; i++)); do
echo $i
done
# Every 2nd number
for ((i=1; i<=100; i+=2)); do
echo $i
done
# Countdown from 100 to 1
for ((i=100; i>=1; i--)); do
echo $i
done

This syntax is familiar to anyone who’s touched C, Java, or JavaScript. Use it when you need conditional increments or complex logic.

While Loops with Counters

A while loop with a manual counter gives you maximum flexibility:

while-counter.sh
i=1
while [ $i -le 100 ]; do
echo $i
((i++))
done

Or countdown:

while-countdown.sh
i=10
while [ $i -gt 0 ]; do
echo "Retry in $i seconds..."
sleep 1
((i--))
done
echo "Go!"

Real-World Example: Batch File Renaming with Counters

Say you have 50 JPG files from your camera and want to rename them sequentially:

rename-photos.sh
#!/bin/bash
counter=1
for file in *.jpg; do
newname=$(printf "photo_%03d.jpg" $counter)
mv "$file" "$newname"
((counter++))
done

The printf "photo_%03d.jpg" gives you photo_001.jpg, photo_002.jpg, etc. — padded with zeros so they sort correctly. Without zero-padding, photo_10.jpg comes before photo_2.jpg alphabetically. Gross.

Practical Example: Retry Loop with Countdown

Deploying something flaky? Retry with a countdown between attempts:

retry-loop.sh
#!/bin/bash
max_attempts=5
attempt=1
while [ $attempt -le $max_attempts ]; do
if curl -s https://api.example.com/health > /dev/null; then
echo "Health check passed!"
exit 0
fi
if [ $attempt -lt $max_attempts ]; then
countdown=5
while [ $countdown -gt 0 ]; do
echo "Attempt $attempt failed. Retrying in $countdown seconds..."
sleep 1
((countdown--))
done
fi
((attempt++))
done
echo "All $max_attempts attempts failed."
exit 1

Looping Over Arrays with Counting

Sometimes you need both the index and the value:

array-loop.sh
fruits=("apple" "banana" "cherry" "date")
# Old school: C-style loop
for ((i=0; i<${#fruits[@]}; i++)); do
echo "$i: ${fruits[$i]}"
done
# Newer bash: loop with index tracking
i=0
for fruit in "${fruits[@]}"; do
echo "$i: $fruit"
((i++))
done

Output: 0: apple, 1: banana, etc.

Progress Percentage Counter

Calculating progress for a long-running loop:

progress.sh
#!/bin/bash
total=100
for ((i=1; i<=total; i++)); do
# Do work here
sleep 0.1
# Calculate percentage
percent=$((i * 100 / total))
printf "\rProgress: %d%%" $percent
done
echo ""
echo "Done!"

The \r carriage return overwrites the same line, giving you a nice progress ticker without spamming your terminal.

Key Takeaways

Pick the right tool for your use case. A simple range loop doesn’t need C-style syntax. But for retries, progress tracking, or countdown logic? That’s where while loops and C-style loops earn their keep. Your future self maintaining this script will appreciate clarity over cleverness.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
Adding Extra Swap to Linux
Next Post
Directory FileCount

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts