in

10 Bash For Loop Examples with Explanations: A Detailed Guide for Beginners

For loops are an essential concept in programming and scripting languages that allow repeating a set of commands iteratively. In Bash shell scripting, for loops provide a handy way to perform operations over collections of data, including arrays, ranges of numbers, strings, command line arguments, and files.

As a beginner exploring Bash scripting, getting a solid grasp on for loops will enable you to start writing scripts for automating tasks and processing data. In this comprehensive guide, we will provide 10 practical examples to demonstrate the most common applications and use cases of Bash for loops.

A Quick Intro to Bash For Loops

Let‘s first cover some for loop basics:

The standard syntax of a for loop in Bash is:

for variable in list_of_items
do
   # commands go here  
done

This structure allows iterating through each item in list_of_items, executing the loop body with variable set to the current item.

The list_of_items can be any list of strings separated by spaces, an array, output of a command, numeral range, etc. The variable name can be any valid name you choose.

The loop body, marked by do and done, will execute once for each item in the list. You can run commands, manipulate data, and work with the current item value in the loop body.

Now let‘s look at examples applying these concepts.

1. Loop Through an Array

Arrays allow storing multiple elements in a single variable. To loop over array items in Bash:

fruits=("Apple" "Banana" "Orange") 

for fruit in "${fruits[@]}";
do
  echo "I like ${fruit}!"
done

Quoting "${fruits[@]}" expands the array so each element is iterated over. Inside the loop, we can reference the current element value with $fruit.

This prints:

I like Apple! 
I like Banana!
I like Orange!

Accessing the array this way is preferred over just $fruits to properly handle spaces and special characters in values.

You can also loop through indexes and values:

for i in "${!fruits[@]}";
do
   echo "${fruits[$i]}" 
done

${!array[@]} prints the indexes rather than values. Combined with accessing ${fruits[$i]} by index, this prints:

Apple
Banana  
Orange

Being able to iterate through indexes as well as values provides added flexibility.

2. Generate a Number Range

Brace expansions provide a convenient way to define a range of numbers to loop through:

for i in {1..5}; 
do
  echo $i
done

This prints from 1 to 5:

1
2
3 
4
5

We can also specify a starting, ending, and increment value:

for i in {0..20..5};
do
  echo $i
done

This will iterate from 0 to 20 in steps of 5:

0 
5
10
15
20

Number ranges provide an easy way to repeat operations a certain number of times.

3. Read a String By Character

To process a string character by character, we can combine substring expansion with the seq command:

word="Linux" 

for i in $(seq 1 ${#word});
do
  char=${word:$i-1:1}
  echo $char
done

Breaking this down:

  • ${#word} gets the length of the string
  • seq 1 ${#word} generates numbers from 1 to the length
  • ${word:$i-1:1} extracts just 1 char at position $i

This loops through and prints each character:

L
i
n
u
x

With this approach, you can easily parse and manipulate string data programmatically.

4. Process Command Line Arguments

Bash scripts can accept command line arguments passed on invocation using $1, $2, etc.

To loop through all arguments, use $#:

total=0

for arg in "$@"; 
do
  total+=$arg
done

echo "Total: $total"

If you run the script like:

./script.sh 10 20 30

It will print:

Total: 60

This provides an easy way to handle multiple arguments of unknown length.

5. Read a File Line By Line

A common scripting task is processing a file line by line. This can be done cleanly using a while loop:

total=0

while read -r line; 
do
  total+=$line
done < file.txt

echo "Total: $total"

This iterates through each line of file.txt, adding it to the total.

This approach avoids loading the entire file contents into memory at once.

6. Loop Continuously with an Infinite Loop

You can create an infinite loop with:

while true
do
  # Loop forever
done

This construct will loop continuously unless forcibly terminated with CTRL+C.

Infinite loops may arise by accident if a terminating condition fails, causing unexpected behavior. So be careful using while true loops in scripts.

7. Break Out of a Loop

The break statement allows exiting a loop immediately when some condition is met:

for i in {1..10};
do
  if [ $i -eq 5 ]; 
  then
    break 
  fi

  echo $i
done 

This will print 1 to 4, then exit the loop once we hit 5.

Breaking conditional on a match provides an early return without having to process remaining iterations unnecessarily.

8. Skip Iterations with Continue

Similar to break, continue skips the current iteration when a condition matches but keeps looping:

for i in {1..10};
do
  if [ $((i % 2)) -eq 0 ]; 
  then
    continue
  fi

  echo $i 
done

This prints all odd numbers from 1 to 10, skipping even values.

Continue is useful for efficiently filtering out unwanted elements.

9. Nest Loops

To add additional looping dimensions, nest For loops:

for i in {1..3};
do
  echo "i: $i"

  for j in {1..3}; 
  do
    echo "  j: $j"
  done
done

The inner loop runs fully on each iteration of the outer loop:

i: 1
  j: 1
  j: 2  
  j: 3

i: 2
  j: 1
  j: 2
  j: 3

i: 3
  j: 1  
  j: 2
  j: 3 

Nesting provides a way to iterate through data organized in matrices and multi-dimensional structures.

10. Loop Through Directories Recursively

We can recurse through subdirectories using globstar **:

shopt -s globstar 

for file in **/*.txt;
do
   echo $file
done

This will print all text files recursively from the current directory down.

Recursion allows processing files in a directory tree without having to hardcode all possible paths.

Key Takeaways

  • For loops provide a mechanism to iterate through items like arrays, numbers, strings, files, and command line arguments.

  • Special variables like $@ and ${array[@]} can be used to conveniently access values.

  • Brace expansions like {1..5} allow quickly defining numeric ranges.

  • break and continue statements add flow control for exiting early or skipping iterations.

  • Watch for infinite loops and mistakenly processing more data than intended.

I hope these examples have provided a solid intro to applying for loops for common scripting tasks. Let me know if you have any other favorite loop examples!

AlexisKestler

Written by Alexis Kestler

A female web designer and programmer - Now is a 36-year IT professional with over 15 years of experience living in NorCal. I enjoy keeping my feet wet in the world of technology through reading, working, and researching topics that pique my interest.