Bash For Loop Explained with Examples

Bash, short for Bourne Again Shell, is a powerful command language interpreter extensively used in Unix-based systems such as Linux and macOS. Among the various types of loops available in Bash, the for loop is one of the most commonly used due to its simplicity and versatility.

The for loop’s ability to handle a wide range of scenarios, from simple lists to complex data structures, makes it an indispensable tool for Bash scripting.

Syntax of Bash For Loop

The for loop in Bash provides a straightforward way to iterate over a list of items, executing a block of code for each item. Understanding its syntax is crucial for effective scripting. The general syntax of a for loop in Bash is as follows:

for variable in list
do
    commands
done

Breakdown of the Syntax

  • for: The keyword that initiates the loop.
  • variable: A placeholder that takes on the value of each item in the list, one at a time.
  • in list: Specifies the list of items to iterate over. This can be a list of strings, numbers, filenames, or the output of a command.
  • do: Indicates the start of the block of commands to be executed for each item.
  • commands: The set of commands to be executed for each item in the list.
  • done: Ends the loop.

Examples of For Loop with Explanation

In this section, we’ll go iover various examples of using for loops in Bash, covering both basic and advanced scenarios. 

Iterating Over a List of Strings

A common use case for the for loop is iterating over a list of strings. Consider the following example:

for color in red green blue
do
    echo "Color: $color"
done

This script will output:

Color: red
Color: green
Color: blue

Explanation:

  • The loop starts with the for keyword.
  • color takes on each value (red, green, blue) from the list.
  • The echo command prints the current value of item.

Iterating Over a Range of Numbers

The for loop can also be used to iterate over a range of numbers. This is particularly useful for tasks that involve numeric sequences. Here’s an example:

for number in {1..5}
do
    echo "Number: $number"
done

The output will be:

Number: 1
Number: 2
Number: 3
Number: 4
Number: 5

Explanation:

  • The loop iterates over numbers from 1 to 5.
  • number takes on each value in the range.
  • The echo command prints the current value of number.

Using Command Substitution

Bash for loops can iterate over the output of commands by using command substitution. For examples

for file in $(ls *.txt)
do
    echo "Processing file: $file"
done

This loop will iterate over all .txt files in the current directory and print a message for each one.

Explanation:

  • The ls command lists files in the specified directory.
  • The for loop iterates over each filename returned by the ls command.
  • The echo command prints each filename.
  • The loop completes after processing all filenames.

Iterating Over Arrays

Arrays in Bash provide a convenient way to store multiple values in a single variable. The for loop can be used to iterate over array elements efficiently.

Defining and Using Arrays

To define an array in Bash, use the following syntax:

array_name=(element1 element2 element3 ...)

Here’s an example of iterating over an array:

fruits=("apple" "banana" "cherry")

for fruit in "${fruits[@]}"
do
    echo "Fruit: $fruit"
done

The Output will be

Fruit: apple
Fruit: banana
Fruit: cherry

Explanation

  • fruits=("apple" "banana" "cherry"): Defines an array with three elements.
  • ${fruits[@]}: References all elements in the array.
  • The for loop iterates over each element, printing the value of fruit.

Nested For Loops

Nested for loops are useful for tasks that require iterating over multiple dimensions, such as matrices or multi-level data structures.

Example: Multiplication Table

Here’s an example that generates a multiplication table:

for i in {1..10}
do
    for j in {1..10}
    do
        echo -n "$((i * j)) "
    done
    echo
done

Explanation

  • The outer loop iterates over numbers 1 to 10 (rows).
  • The inner loop iterates over numbers 1 to 10 (columns).
  • $((i * j)): Performs multiplication of i and j.
  • echo -n: Prints the result without a newline, keeping numbers on the same row.
  • The echo command outside the inner loop prints a newline after each row.

Example: Nested Loops with Arrays

Consider a scenario where you need to combine elements from two arrays:

colors=("red" "green" "blue")
shapes=("circle" "square" "triangle")

for color in "${colors[@]}"
do
    for shape in "${shapes[@]}"
    do
        echo "$color $shape"
    done
done

Explanation

  • The outer loop iterates over each color.
  • The inner loop iterates over each shape.
  • The combination of color and shape is printed for each iteration of the inner loop.

Conditional Loops: break and continue Statements

In complex scripts, you may need more control over the flow of your for loops. Bash provides break and continue statements to manage loop execution conditionally.

Using break

The break statement exits the loop prematurely when a specified condition is met. This is useful when you need to terminate the loop early.

for number in {1..10}
do
    if [ "$number" -eq 5 ]; then
        break
    fi
    echo "Number: $number"
done

Explanation

  • The loop iterates over numbers from 1 to 10.
  • if [ "$number" -eq 5 ]; then break; fi: Exits the loop when the number is 5.
  • The script prints numbers 1 to 4 and then exits the loop.

Using continue

The continue statement skips the rest of the current loop iteration and moves to the next iteration. This is useful for skipping certain conditions without exiting the loop entirely.

for number in {1..10}
do
    if [ "$number" -eq 5 ]; then
        continue
    fi
    echo "Number: $number"
done

Explanation

  • The loop iterates over numbers from 1 to 10.
  • if [ "$number" -eq 5 ]; then continue; fi: Skips the iteration when the number is 5.
  • The script prints numbers 1 to 4 and 6 to 10, skipping 5.

File Manipulation

File manipulation is a common task in system administration and development workflows. The for loop simplifies batch processing of files, making it efficient and less error-prone.

Batch Renaming Files

Consider a scenario where you need to rename multiple files by adding a prefix or suffix to their names:

prefix="backup_"
for file in *.txt
do
    mv "$file" "${prefix}${file}"
done

Explanation

  • .txt: Glob pattern to match all .txt files in the directory.
  • mv "$file" "${prefix}${file}": Renames each file by adding the prefix.

Moving Files Based on Extension

Another common task is moving files to different directories based on their extensions:

mkdir -p images documents
for file in *
do
    case "$file" in
        *.jpg|*.png) mv "$file" images/ ;;
        *.doc|*.pdf) mv "$file" documents/ ;;
    esac
done

Explanation

  • mkdir -p images documents: Creates target directories if they don’t exist.
  • case "$file": Checks the file extension and moves the file accordingly.

System Administration Tasks

System administrators often use Bash scripts to automate routine tasks. The for loop is particularly useful for managing users, packages, and system configurations.

Automating User Creation

Creating multiple user accounts can be automated with a for loop:

for user in user1 user2 user3
do
    sudo useradd "$user"
    echo "Created user: $user"
done

Explanation

  • sudo useradd "$user": Adds each user specified in the list.
  • echo "Created user: $user": Confirms the creation of each user.

Installing Packages

Automating the installation of a list of packages ensures consistency across multiple systems:

packages=(vim git curl)
for package in "${packages[@]}"
do
    sudo apt-get install -y "$package"
done

Explanation

  • packages=(vim git curl): Defines an array of package names.
  • sudo apt-get install -y "$package": Installs each package without prompting for confirmation.

Shell Globbing: Using Wildcards

Shell globbing refers to the use of wildcard characters to match filenames. This feature allows you to efficiently select groups of files based on patterns.

Common Wildcards

  • *: Matches any number of characters, including none.
  • ?: Matches exactly one character.
  • [abc]: Matches any one of the characters inside the brackets.
    • Example: file[123].txt matches file1.txt, file2.txt, and file3.txt.
for file in *.log
do
    echo "Processing file: $file"
    # Process each log file
done

Explanation

  • .log: Matches all files with the .log extension.
  • The loop processes each matched file.

Conclusion

With Bash for loops in your scripting toolkit, you’ll be able to automate tasks, process data efficiently, and tackle complex challenges with ease. Now that you understand the fundamentals, go forth and unlock the full power of Bash scripting. Happy coding!

Share your love

Newsletter Updates

Stay updated with our latest guides and tutorials about Linux.

Leave a Reply

Your email address will not be published. Required fields are marked *