For Loops
For loops are one of the most powerful and commonly used control structures in Bash. They allow you to iterate over lists, arrays, file sets, command output, and numeric ranges. Mastering for loops is essential for processing multiple items, automating repetitive tasks, and building efficient shell scripts!
Basic For-In Loop
The most common type of for loop iterates over a list of items. Each item is assigned to the loop variable and processed.
Click Run to execute your code
# Basic syntax
for variable in item1 item2 item3; do
# code to execute for each item
done
# Example
for fruit in apple banana cherry; do
echo "Fruit: $fruit"
done
# Output:
# Fruit: apple
# Fruit: banana
# Fruit: cherry
-
for variable in list starts the loop-
do begins the loop body-
done ends the loop- Loop variable is available as
$variable inside the loop
Iterating Over Arrays
For loops are perfect for processing arrays. Use "${array[@]}" to iterate over all elements.
# Array iteration
fruits=("apple" "banana" "cherry")
for fruit in "${fruits[@]}"; do
echo "$fruit"
done
# Iterating with index
for i in "${!fruits[@]}"; do
echo "Index $i: ${fruits[$i]}"
done
"${array[@]}" to preserve elements with spaces. Without quotes, elements with spaces will be split into multiple loop iterations.
C-Style For Loop
Bash supports C-style for loops for numeric iteration. This syntax is useful for counting and numeric ranges.
# C-style syntax
for ((initialization; condition; increment)); do
# code
done
# Example: Count from 1 to 5
for ((i=1; i<=5; i++)); do
echo "Count: $i"
done
# Example: Count by 2
for ((i=0; i<=10; i+=2)); do
echo "$i"
done
# Example: Countdown
for ((i=5; i>=1; i--)); do
echo "Countdown: $i"
done
Click Run to execute your code
Using Brace Expansion for Ranges
Brace expansion provides an easy way to generate number sequences without using C-style loops.
# Number ranges
for num in {1..5}; do
echo "Number: $num"
done
# With step (Bash 4+)
for num in {0..10..2}; do
echo "$num"
done
# Character ranges
for letter in {a..e}; do
echo "$letter"
done
# Reverse ranges
for num in {5..1}; do
echo "Countdown: $num"
done
Iterating Over Command Output
For loops can iterate over the output of commands. Each line becomes an iteration.
# Iterate over file listing
for file in $(ls /bin); do
echo "File: $file"
done
# Iterate over lines in a file
for line in $(cat file.txt); do
echo "Line: $line"
done
# Better: using while read for files (preserves spaces)
while IFS= read -r line; do
echo "$line"
done < file.txt
while read instead of for to preserve whitespace. Command substitution with $() splits on spaces by default.
Iterating Over Script Arguments
For loops can process command-line arguments passed to your script.
# Iterate over all arguments
for arg in "$@"; do
echo "Argument: $arg"
done
# Shorthand: "$@" is default for for loop
for arg; do
echo "Argument: $arg"
done
# Iterate with index
i=1
for arg in "$@"; do
echo "Argument $i: $arg"
((i++))
done
Nested For Loops
You can nest for loops inside other for loops to create multi-dimensional iterations.
# Nested loops
for i in {1..3}; do
for j in {a..c}; do
echo "$i$j"
done
done
# Output:
# 1a, 1b, 1c, 2a, 2b, 2c, 3a, 3b, 3c
Common Mistakes
1. Not quoting array expansion
# Wrong - elements with spaces get split
files=("file one.txt" "file two.txt")
for file in ${files[@]}; do
echo "$file" # Prints: file, one.txt, file, two.txt
done
# Correct - quote the expansion
for file in "${files[@]}"; do
echo "$file" # Prints: file one.txt, file two.txt
done
2. Using $variable instead of just variable in C-style loop
# Wrong - $ not needed in (( ))
for (($i=1; $i<=5; $i++)); do # Syntax error!
echo "$i"
done
# Correct - no $ in arithmetic context
for ((i=1; i<=5; i++)); do
echo "$i"
done
3. Using for to read files line by line
# Wrong - splits on spaces, not lines
for line in $(cat file.txt); do
echo "$line"
done
# Correct - use while read
while IFS= read -r line; do
echo "$line"
done < file.txt
Exercise: Process Multiple Files
Task: Create a script that processes multiple items using for loops!
Requirements:
- Use a for-in loop to iterate over a list of items
- Use a C-style for loop to count from 1 to 10
- Iterate over an array and process each element
- Use brace expansion to generate a range
- Create a nested loop (optional: multiplication table)
Show Solution
#!/bin/bash
# For loop exercises
# 1. For-in loop
echo "Fruits:"
for fruit in apple banana cherry; do
echo " - $fruit"
done
# 2. C-style loop
echo -e "\nCounting 1-10:"
for ((i=1; i<=10; i++)); do
echo " $i"
done
# 3. Array iteration
echo -e "\nColors:"
colors=("red" "green" "blue")
for color in "${colors[@]}"; do
echo " $color"
done
# 4. Brace expansion
echo -e "\nNumbers 1-5:"
for num in {1..5}; do
echo " $num"
done
# 5. Nested loop (multiplication table)
echo -e "\nMultiplication table (2x):"
for i in {1..5}; do
for j in {1..3}; do
result=$((i * j))
echo -n " $i×$j=$result"
done
echo ""
done
Summary
- For-In:
for var in list; do ... doneiterates over items - C-Style:
for ((i=1; i<=5; i++)); do ... donefor numeric loops - Arrays: Use
"${array[@]}"(quoted) to preserve spaces - Ranges: Use
{1..5}or C-style for numeric sequences - Arguments: Use
"$@"to iterate over script arguments - Command Output: Use
$(command)but beware of space splitting - Files: Use
while readinstead offorfor line-by-line - Nested: For loops can be nested for multi-dimensional iteration
What's Next?
Perfect! You've mastered for loops for iteration. Next, we'll learn about While & Until Loops - control structures that continue looping based on conditions rather than iterating over lists. These are essential for reading files, waiting for conditions, and creating interactive scripts!
Enjoying these tutorials?