for Loops
Prerequisites: Wildcards and globbing, Quoting
A for loop runs commands once for each item in a list.
Syntax
for variable in item1 item2 item3; do
commands
done
Looping over words, ranges, and files
for fruit in apple banana cherry; do
echo "I like $fruit"
done
for i in {1..3}; do
echo "Pass $i"
done
touch jan.csv feb.csv mar.csv
for file in *.csv; do
echo "Found $file"
done
I like apple
I like banana
I like cherry
Pass 1
Pass 2
Pass 3
Found feb.csv
Found jan.csv
Found mar.csv
Looping over a wildcard is the safe way to process files — each file name
arrives intact, even with spaces, as long as you quote "$file" when you
use it.
A practical example: batch rename
touch "IMG 001.jpg" "IMG 002.jpg" "IMG 003.jpg"
for file in IMG*.jpg; do
new="holiday-${file#IMG }"
mv "$file" "$new"
done
ls
holiday-001.jpg
holiday-002.jpg
holiday-003.jpg
${file#IMG } removes IMG from the start of the name — one of Bash's
string operations, covered in Level 2.
C-style loop
for (( i = 10; i > 0; i -= 3 )); do
echo "$i"
done
10
7
4
1
Common mistakes
- Looping over
$(ls)or$(find ...)— names with spaces get split into pieces. Loop over a wildcard, or use thefind/while readpatterns in Level 2. - Forgetting to quote
"$file"inside the loop.
Practice
Print the 5 times table from 5 x 1 = 5 to 5 x 10 = 50.
Show solution
for n in {1..10}; do
echo "5 x $n = $(( 5 * n ))"
done
5 x 1 = 5
5 x 2 = 10
5 x 3 = 15
5 x 4 = 20
5 x 5 = 25
5 x 6 = 30
5 x 7 = 35
5 x 8 = 40
5 x 9 = 45
5 x 10 = 50