This post was originally published on go2linux.org on March 31, 2010. The domain is no longer mine, but I am the original author. I am republishing it here on garron.me with corrections and improvements.

Introduction

A for loop executes a block of commands repeatedly, once for each item in a list. It is one of the most used constructs in bash scripting.

Basic syntax

For use at the command line:

for NAME [in WORDS ...]; do COMMANDS; done

In a script, spread across multiple lines:

for i in list
do
    commands
done

Examples

Print all files in the current directory

for i in $(ls); do echo $i; done

For every value that ls returns, the loop assigns it to i and prints it.

Counting with a for loop

Using C-style syntax

#!/bin/bash
for ((i=1; i<=25; i+=1))
do
    echo $i
done

Using a brace expansion range

#!/bin/bash
for i in {1..25}
do
    echo $i
done

Counting in steps of 5

#!/bin/bash
for i in {0..25..5}
do
    echo $i
done

Output:

0
5
10
15
20
25

Counting backwards

#!/bin/bash
for i in {25..0..-5}
do
    echo $i
done

Output:

25
20
15
10
5
0

You can also use C-style syntax:

#!/bin/bash
for ((i=25; i>=0; i-=5))
do
    echo $i
done

break and continue

Stop the loop early with break

#!/bin/bash
for i in {1..25}
do
    echo $i
    if [ "$i" = "15" ]
    then
        break
    fi
done

This stops the loop as soon as i reaches 15.

Skip an iteration with continue

#!/bin/bash
for i in {1..25}
do
    if [ "$i" = "15" ]
    then
        continue
    fi
    echo $i
done

This prints all numbers from 1 to 25 except 15. When i equals 15, continue jumps to the next iteration without executing the echo.

Iterating over files

A common real-world use is processing a set of files:

#!/bin/bash
for f in /var/log/*.log
do
    echo "Processing $f"
    gzip "$f"
done

Iterating over command output

#!/bin/bash
for user in $(cut -d: -f1 /etc/passwd)
do
    echo "User: $user"
done