Imagine you have a directory filled with thousands of files, and you have been asked to process these files one by one. Sounds quite tedious, right? Well not, if you are using For loops in Bash script. For loop in bash script is a magical tool that can help you automate any repetitive task while efficiently handling those files without breaking a sweat. In this article, we discuss what are for loops in bash with some practical examples to make automation a child’s play.
What is For Loop in Bash Script
For loop is a control structure that is used to perform repetitive tasks or execute a bunch of commands a specific number of times. With for loop, you can iterate through numbers, lists, files, or even directories.
Bash For Loop: POSIX Style Syntax
The POSIX (Portable Operating System Interface) style syntax can be used with POSIX compliant shells like bash and can be used to iterate over a list of files, any sequence, or even the output of other commands. Here is the for loop syntax in bash script:
for <loop_variable> in <list_to_iterate>
do
<Commands_to_be_executed_in_each_iteration>
done
In the above syntax, here’s what everything means:
- <loop_variable> is a user-defined variable that holds each item from the <list_to_iterate>.
- <list_to_iterate> refers to the list of items over which the for loop is needed to iterate. It can be a list of numbers, strings, output of a command, etc.
- do keyword signifies the start of the for loop.
- <Commands_to_be_executed_in_each_iteration> contains the commands or statements which will be executed for every iteration.
- done keyword signifies the end of the for loop.
Let us now see some practical examples based on the POSIX style for loop:
Example 1: Loop through a Given Range
#!/bin/bash
# Print numbers from 1 to 5
for i in $(seq 1 5); do
echo $i
done
In the above snippet, the $(seq 1 5) part is used to generate a list of integers from 1 to 5. It will then loop over the list one by one and then each value will get printed on a new line.
Example 2: Loop through an Array
#!/bin/bash
fruits=("Apple" "Banana" "Orange" "Grapes")
for fruit in "${fruits[@]}"; do
echo "Fruit: $fruit"
done
An array is a data structure that is used to contain multiple data of different types. In the above snippet:
- The line
fruits=("Apple" "Banana" "Orange" "Grapes")
is used to declare the array containing four different fruit names. - The line “
for fruit in "${fruits[@]}"; do
” sets up the For Loop. It specifies the variable “fruit” to hold the current element value and “${fruits[@]}
” as the array to be iterated. The “@
“, within “${fruits[@]}
“, represents all the elements of the array. - The line “
echo "Fruit: $fruit"
” prints each fruit name on a new line along with the word “Fruit” during each iteration. - Finally the last line “done” signifies the end of the for loop.
Here is the output we will get from the above commands:
Example 3: Loop with Command Substitution
#!/bin/bash
for file in $(ls); do
echo "File: $file"
done
The way command substitution works is, the command gets first executed and then the for loop will iterate through the entire output of the command. The command to be iterated upon is placed inside “$()
“. In the above snippet:
- In the line
for file in $(ls); do
, the$(ls)
part executes the ‘ls’ command then and its output (the list of files in the current directory) is used as input for the loop. The loop will iterate through each file name found in the output. - The line
echo "File: $file"
prints the value of the “file” variable along with the prefix “File: ” during each iteration. The “file” variable contains the name of the current file being processed in the loop. - Finally the last line “done” signifies the end of the for loop.
The output for the for loop with command substitution as demonstrated in the above example would be:
Bash For Loop: C Style Syntax
The C style syntax suits users who are more accustomed to the for loop syntax in other languages like C, C++, Java, JavaScript, etc. Here is the basic syntax to the C style for loop:
for ((<variable_initialization>; <test_condition>; <step_value>))
do
<commands_to_execute>
done
In the above syntax:
<variable_initialization>
refers to the initial value the loop variable will start from.<test_condition>
defines the condition on which the output will depend; this condition is checked in each iteration.<step_value>
refers to the value by which the loop variable needs to get updated.- <commands_to_execute> refers to the commands or statements that need to be executed for each iteration.
Let us now see some practical examples based on the C style for loop:
Example 1: Print Odd Numbers from 1 to 10
!#/bin/bash
for((i = 1; i <= 10; i = i + 1))
do
if (( i % 2 == 1 ))
then
echo "Odd Number: $i"
fi
done
In the above snippet:
- The line
for((i = 1; i <= 10; i = i + 1))
initializes the loop variable to 1, checks if the “value of i is less or equals to 10” for every iteration, and finally increments the value of i by adding 1 to the current value after every iteration. - if (( i % 2 == 1 )) checks if the remainder value on dividing the current value of i with 2 is equal to 1 or not –
- if divisible, then the line echo “Odd Number: $i” gets executed printing the value of i.
- the line fi signifies the end of the if condition.
- Finally, the last line demarcates the end of the for loop and gets executed at the end.
Here is the output you will get for the above code:
Example 2: Loop through an Array
#!/bin/bash
fruits=("Apple" "Banana" "Orange" "Grapes")
for ((i = 0; i < ${#fruits[@]}; i++)); do
echo "Fruit $((i+1)): ${fruits[i]}"
done
In the above code:
- fruits=(“Apple” “Banana” “Orange” “Grapes”) creates an array of all fruit names.
- for ((i = 0; i < ${#fruits[@]}; i++)) first initializes the loop variable “i” to 0 which will act as the index variable for array also, and the loop continues as long as “i” is less than the number of elements in the “fruits” array (denoted by ${#fruits[@]}). The loop increments “i” by 1 in each iteration.
- Since array indices start from 0 but we want to display them as starting from 1, the line echo “Fruit $((i+1)): ${fruits[i]}” prints the value that is equal to the current index “i” plus 1.
- Finally, the last line signifies the end of the for loop
Here is the output of the above for loop: