Bash For Loop
Updated on
•6 min read

Loops are one of the fundamental concepts of programming languages. They are handy when you want to run a series of commands repeatedly until a specific condition is reached.
In scripting languages like Bash, loops are useful for automating repetitive tasks, eliminating the need to write the same code repeatedly.
There are three basic loop constructs in Bash scripting: for
loop, while
loop
, and until
loop
.
In this article, we will cover the basics of the for
loops in Bash and show you how to use the break
and continue
statements to alter the flow of a loop.
The Standard Bash for
Loop
The for
loop iterates over a list of items and performs the given set of commands.
The Bash for
loop takes the following form:
for item in [LIST]
do
[COMMANDS]
done
The list can be a series of strings separated by spaces, a range of numbers, the output of a command, an array, arguments passed from the command line, and so on.
Loop over strings
The example below shows a loop that iterates over a list of strings. The loop operates on each item in the list, and the variable element
stores the item that the loop is currently operating on.
for element in Hydrogen Helium Lithium Beryllium
do
echo "Element: $element"
done
The loop will produce the following output:
Element: Hydrogen
Element: Helium
Element: Lithium
Element: Beryllium
Loop over a range
You can use the sequence expression to specify a range of numbers or characters by defining the start and the end point of the range. The sequence expression takes the following form:
{START..END}
Here is an example loop that iterates through all numbers from 0 to 3:
for i in {0..3}
do
echo "Number: $i"
done
Number: 0
Number: 1
Number: 2
Number: 3
Starting from Bash 4, it is also possible to specify an increment when using ranges. The expression takes the following form:
{START..END..INCREMENT}
Here’s an example showing how to increment by 5:
for i in {0..20..5}
do
echo "Number: $i"
done
Number: 0
Number: 5
Number: 10
Number: 15
Number: 20
Loop over array elements
You can also use the for
loop to iterate over an array of elements.
In the example below, we define an array named BOOKS
and iterate over each element of the array.
BOOKS=('In Search of Lost Time' 'Don Quixote' 'Ulysses' 'The Great Gatsby')
for book in "${BOOKS[@]}"; do
echo "Book: $book"
done
Book: In Search of Lost Time
Book: Don Quixote
Book: Ulysses
Book: The Great Gatsby
The C-style Bash for loop
The syntax of the C-style for
loop takes the following form:
for ((INITIALIZATION; TEST; STEP))
do
[COMMANDS]
done
The INITIALIZATION
part is executed only once when the loop starts. Then, the TEST
part is evaluated. If it is false, the loop is terminated. If the TEST
is true, commands inside the body of the for
loop are executed, and the STEP
part is updated.
In the following example code, the loop starts by initializing i = 0
, and before each iteration, checks if i ≤ 10
. If true, it prints
the current value of i
and [increments the variable] i
by 1 (i++
). Otherwise, the loop terminates.
for ((i = 0 ; i <= 1000 ; i++)); do
echo "Counter: $i"
done
The loop will iterate 1001 times and produce the following output:
Counter: 0
Counter: 1
Counter: 2
...
Counter: 998
Counter: 999
Counter: 1000
Nesting Loops
A nested loop is a loop inside another loop. You can nest any loop for any number of times.
In a nested for loop, the inner loop runs a complete cycle of its iterations for every outer loop iteration. This means that for every execution of the outer loop, the inner loop will execute all of its iterations until the outer loop completes its cycle.
Here’s an example code that copies three files one by one to three servers.
for f in file_{1..3}; do
for j in server_{1..3}; do
echo "Copying file $f to server $j";
# command to copy files
done;
done
Copying file file_1 to server server_1
Copying file file_1 to server server_2
Copying file file_1 to server server_3
Copying file file_2 to server server_1
Copying file file_2 to server server_2
Copying file file_2 to server server_3
Copying file file_3 to server server_1
Copying file file_3 to server server_2
Copying file file_3 to server server_3
break
and continue
Statements
The break
and continue
statements
can be used to control the for
loop execution.
break
Statement
The break
statement terminates the current loop and passes program control to the statement that follows the terminated statement. It is generally used to terminate the loop when a specific condition is met.
In the following example, we use the if
statement
to terminate the execution of the loop once the current iterated item is equal to ‘Lithium’.
for element in Hydrogen Helium Lithium Beryllium; do
if [[ "$element" == 'Lithium' ]]; then
break
fi
echo "Element: $element"
done
echo 'All Done!'
Element: Hydrogen
Element: Helium
All Done!
continue
Statement
The continue
statement exits the current iteration of a loop and passes program control to the next iteration of the loop.
In the following example, we are iterating through a range of numbers. When the current iterated item is equal to ‘2’, the continue
statement will cause execution to return to the beginning of the loop and to continue with the next iteration:
for i in {1..5}; do
if [[ "$i" == '2' ]]; then
continue
fi
echo "Number: $i"
done
Number: 1
Number: 3
Number: 4
Number: 5
Bash for
Loop Examples
Renaming files with spaces in the filename
The following example shows how to rename all of the files in the current directory with a space in its names by replacing the spaces to underscores:
for file in *\ *; do
mv "$file" "${file// /_}"
done
Let’s break down the code line by line:
- The first line creates a
for
loop and iterates through a list of all files with a space in its name. The expression*\ *
creates the list. - The second line applies to each item of the list and moves the file to a new one, replacing the space with an underscore (
_
). The part${file// /_}
is using the shell parameter expansion to replace a pattern within a parameter with a string. done
indicates the end of the loop segment.
Changing file extension
The following example shows how to use the Bash for
loop to rename all files
ending with .jpeg in the current directory by replacing the file extension from .jpeg to .jpg.
for file in *.jpeg; do
mv -- "$file" "${file%.jpeg}.jpg"
done
Let’s analyze the code line by line:
- The first line creates a
for
loop and iterates through a list of all files ending with ‘.jpeg’. - The second line applies to each item of the list and moves the file to a new one, replacing ‘.jpeg’ with ‘.jpg’.
${file%.jpeg}
to remove the ‘.jpeg’ part from the filename using the shell parameter expansion done
indicates the end of the loop segment.
Conclusion
The Bash for
loop is used to execute a given set of commands repeatedly for a fixed number of times.
If you have any questions or feedback, feel free to leave a comment.