For Loops
For loops allow you to iterate over a list of items, executing commands for each one. They're essential for processing files, arrays, and sequences.
Basic For Loop Syntax
for variable in list; do
commands
done
The variable takes each value in the list, one at a time.
Looping Over a List
#!/bin/bash
for fruit in apple banana cherry; do
echo "I like $fruit"
done
Output:
I like apple
I like banana
I like cherry
Looping Over Files
One of the most common uses:
#!/bin/bash
# Process all .txt files
for file in *.txt; do
echo "Processing: $file"
wc -l "$file"
done
Handle the case when no files match:
#!/bin/bash
shopt -s nullglob # Pattern expands to nothing if no match
for file in *.txt; do
echo "Found: $file"
done
Exercise: Loop Over Items
Use a for loop:
Using Brace Expansion
Generate sequences easily:
# Numbers
for i in {1..5}; do
echo "Count: $i"
done
# With step
for i in {0..10..2}; do # 0, 2, 4, 6, 8, 10
echo "$i"
done
# Letters
for letter in {a..e}; do
echo "$letter"
done
# Padding with zeros
for i in {01..10}; do
echo "file$i.txt"
done
Using Command Output
Loop over command output:
#!/bin/bash
# Loop over files from find
for file in $(find . -name "*.sh"); do
echo "Script: $file"
done
# Loop over lines (be careful with whitespace!)
for user in $(cat /etc/passwd | cut -d: -f1); do
echo "User: $user"
done
Warning: Word splitting happens! Use while read for lines with spaces.
C-Style For Loop
Familiar syntax for programmers:
for ((initialization; condition; increment)); do
commands
done
Examples:
#!/bin/bash
# Count from 0 to 4
for ((i=0; i<5; i++)); do
echo "i = $i"
done
# Countdown
for ((i=10; i>=0; i--)); do
echo "$i..."
done
echo "Liftoff!"
# Multiple variables
for ((i=0, j=10; i<5; i++, j--)); do
echo "i=$i, j=$j"
done
Exercise: C-Style Loop
Use the C-style for loop:
Looping Over Arrays
Iterate through array elements:
#!/bin/bash
FRUITS=("apple" "banana" "cherry" "date")
# Loop over all elements
for fruit in "${FRUITS[@]}"; do
echo "Fruit: $fruit"
done
# Loop with indices
for i in "${!FRUITS[@]}"; do
echo "$i: ${FRUITS[$i]}"
done
Looping Over Command Line Arguments
Process all script arguments:
#!/bin/bash
# process_files.sh
for arg in "$@"; do
echo "Processing: $arg"
done
Run with: ./process_files.sh file1.txt file2.txt file3.txt
Nested For Loops
Loops within loops:
#!/bin/bash
for i in {1..3}; do
for j in {1..3}; do
echo "i=$i, j=$j"
done
done
# Create multiplication table
for i in {1..5}; do
for j in {1..5}; do
printf "%4d" $((i * j))
done
echo # Newline
done
Loop Variable Scope
The loop variable persists after the loop:
#!/bin/bash
for i in 1 2 3; do
echo "$i"
done
echo "After loop: $i" # Prints: 3
Infinite For Loop
Create a loop that runs forever:
#!/bin/bash
for (( ; ; )); do
echo "Running..."
sleep 1
done
# Or using while
for item in $(cat); do
# Reads from stdin until EOF
echo "$item"
done
Practical Example: Batch Rename
#!/bin/bash
# Rename all .txt to .bak
for file in *.txt; do
if [ -f "$file" ]; then
newname="${file%.txt}.bak"
echo "Renaming $file to $newname"
mv "$file" "$newname"
fi
done
For Loop One-Liners
Quick loops on the command line:
# Create multiple directories
for d in dir1 dir2 dir3; do mkdir -p "$d"; done
# Check multiple hosts
for host in server1 server2 server3; do ping -c 1 "$host"; done
# Process numbered files
for i in {1..10}; do touch "file$i.txt"; done
Exercise: Process Files
Loop over files in a directory:
Best Practices
- Always quote variables:
for file in "$@"notfor file in $@ - Use
"${array[@]}"for arrays: Preserves elements with spaces - Be careful with command substitution: Word splitting can cause issues
- Use meaningful variable names:
for file in *.txtnotfor x in *.txt - Handle empty lists: Use
shopt -s nullglobor check if list is empty
# Good practice
for file in *.txt; do
[ -f "$file" ] || continue # Skip if no match
process "$file"
done
# Better with nullglob
shopt -s nullglob
for file in *.txt; do
process "$file"
done
shopt -u nullglob
Key Takeaways
for var in list; do ... doneiterates over items- Use brace expansion
{1..10}for number sequences - Use
*.txtto loop over files matching a pattern - C-style
for ((i=0; i<10; i++))for traditional loops - Loop over arrays with
"${array[@]}" - Loop over arguments with
"$@" - Always quote variables to handle spaces correctly
- Use
shopt -s nullglobwhen globbing might match nothing

