Reading a file line by line is a must-have skill that any developer needs to learn to master bash scripting. One of the easiest methods to read file content is the use of a read command in conjunction with a while loop that loops through a file line by line and facilitates data manipulation and processing. The while loop with the read command can be used in various ways for reading file information. In this article, I will walk you through the 8 cases to read a file line with the while loop in Bash. Stay tuned.
8 Cases to Read File Line Using “while” Loop in Bash
A while loop offers versatile features, so it can be used in combination with the read command in 8 ways to read a file line. Here. I will explain how the read, cat, awk, grep, etc. commands are used for reading file content. Additionally, to read file lines using command-line argument, IFS variable, and process substitution will also be addressed.
Download this file.txt to work with the following methods. Here’s the content of the file:
1. Using “read” Command Alone
To read a file line in bash, use only the read command within the while loop. The read command can read an entire file line by line through a while loop. Follow the script below to see how the while loop works with the read
command for reading file lines:
#!/bin/bash
filename="file.txt"
while read line; do
echo $line
done < "$filename"
Here, filename="file.txt"
assigns the file.txt to the variable filename. Then the while read line; do
starts the while loop and continues to read file line by line and echoes each line (read by the read
command) to the terminal with the echo $line
. Finally, the done < $filename
uses input redirection (<)
to redirect the input from the file specified by the “filename” variable.
This picture shows that the script prints each line of file.txt. However, it does not show the backslash sign \ from the file. To preserve the backslashes, use the -r
option with the read
command. Here’s how:
#!/bin/bash
filename="file.txt"
while read -r line; do
echo $line
done < "$filename"
The while read
command with the -r
option reads the file line from “file.txt” including backslashes and prints the line that is read by the read
command in the terminal using the echo command.
Now, you can see that the file is read including backslashes by the read command in a while loop.
2. Using “cat” Command
In this example, the cat command is piped with the while read -r line
to read line from the file.txt. The piping operator |
is used to take the output of the cat command as input of the while loop. Copy the script to read a file line using the cat
command:
#!/bin/bash
filename="file.txt"
cat "$filename" | while read -r line
do
echo $line
done
The cat
command concatenates and displays the content of the specified file. Then the output is piped to the while loop as input. Lastly, the while loop
with the read -r
command reads each line of the file.txt and prints the read line in the terminal using the echo
command.
As you can see, the script reads the file content and prints it in the terminal.
3. Using IFS (Internal Field Separator)
Within a while loop, the IFS (Internal Field Separator) can be incorporated with the read
command to read a file line by line. The value of IFS determines which characters are treated as field separators. Now, take a look at the following bash script to use the IFS
with a while
loop to read file content:
#!/bin/bash
filename="file.txt"
while IFS= read -r line
do
echo $line
done < "$filename"
while IFS= read -r line
reads line by line from the file.txt. Here, the IFS
sets to nothing to preserve the leading and trailing whitespaces. After that, the echo
command prints each read line by the while loop.
You can see in the image that all the lines of the “file.txt” are printed on the terminal.
4. Using Command-line Argument
In this example, to read the file content, the filename will be taken as a command-line argument. Here, the $1
is a positional parameter indicating the first argument passed to the script. To know how to use it for reading file lines, check the script below:
#!/bin/bash
filename=$1
while read -r line; do
echo $line
done < $filename
Before starting the while loop, the $1
passed the file.txt from the command line to the variable filename. Then the while read -r line
continues to read the file content including the backslash character due to the -r
option with the read
command. After reading the entire file, the script outputs the content to the console by the echo
command.
Run the script with this command to get the following output:
./argument.sh file.txt
As you can see, every line of the file.txt is shown on the terminal.
5. Using “awk” Command
A powerful text-processing tool in Linux and other Unix-like operating systems is the awk command. In order to read the file line by line, the while loop is piped with the awk
command here:
#!/bin/bash
filename="file.txt"
awk '{print}' "$filename" | while read -r line
do
echo $line
done
The script uses the awk
command to print each line of the file.txt specified by the variable filename. Then the output of this command is passed to the while
loop as input through the pipe operator. while read -r line
reads file lines from the standard input (the output of the awk
command) and prints them in the terminal using echo $line
.
The image illustrates each line of the “file.txt” read by the while loop.
6. Using here String
The here string in bash passes a string as the input to a command using the <<<
operator. This example shows how to use this here string
operator to read a file line by line. To achieve this, copy the script:
#!/bin/bash
filename="file.txt"
while read -r line
do
echo "$line"
done <<< "$(cat "$filename")"
After assigning the file.txt to the variable filename, while read -r line
continues to read the file line one by one. The echo
command displays each line to the console. done <<< "$(cat "$filename")"
uses here string operator <<<
to provide the file content as input to the while loop. The cat $filename
reads the contents of the file and the output is captured by the command substitution “$(…)”.
Upon script execution, the file contents are shown in the output.
7. Using File Descriptor
This example shows how to use a file descriptor within a while
loop to read a file line. The file descriptor in Bash is a non-negative unique identifier for an open file or input/output stream. It represents what is connected to the shell script whether it is a file, network connection, or terminal.
The reserved file descriptors are as follows:
- File Descriptor 0 (standard input): The stream from which a command reads its input data. It is connected to the keyboard by default.
- File Descriptor 1 (standard output): The stream to which a command writes its output data. It is connected to the terminal by default.
- File Descriptor 2 (standard error): The stream from which a command writes its error messages. It is connected to the terminal by default.
The file descriptors beyond 2 are used to represent other streams like an open file or network connections.
In the following script, the file descriptor 3 is used for the file named “file.txt” to read the contents of the file:
#!/bin/bash
while IFS= read -r -u3 line; do
echo "$line"
done 3< file.txt
The script initiates a while loop that reads each line from the file descriptor 3 (u3)
and stores it in the variable line. The IFS is set to empty string to avoid unintended word spitting and the -r
option preserves the backslash characters. echo "$line"
prints the current read line of the file. done 3< file.txt
redirects the “file.txt” to the file descriptor 3 which means the read
command will read from this file.
Every line that was read from the file.txt is shown in the image.
8. Using Process Substitution
Process substitution uses <(...)
syntax to create a temporary file from the output of a command that allows direct use as input for other commands. In this example, for reading file lines of the file.txt, process substitution is used. Follow the script to know more about it:
#!/bin/bash
while IFS= read -r line; do
echo "$line"
done < <(cat file.txt)
while IFS= read -r line; do
starts a while loop that reads each line from the input source preserving the whitespaces and prints the read line in the terminal. done < <(cat file.txt)
uses process substitution <(...)
that creates a temporary file-like stream from the output of the cat file.txt
command and redirects the output to the standard input of the while loop.
You can see the read line from the “file.txt” file in this picture.
To read a file line, you can also use grep command with the process substitution operator <(...)
that takes the output of the grep
command as input and redirects it to the while loop. Copy the script below to achieve this task:
#!/bin/bash
filename="file.txt"
while IFS= read -r line
do
echo "$line"
done < <(grep "" "$filename")
The while IFS= read -r line
initiates a while loop that reads each line from the output of the grep "" "$filename"
command and prints the lines in the terminal using the echo
command. The grep ""
part is used here to read all lines from the file.
The image shows all the lines of the “file.txt” read by the grep command.
How to Read File Line in Reverse Order?
Using a while loop with the tac
command, a file line can be read in reverse order. The tac command concatenates and displays the contents of the file reversely. The while loop is combined with a for
loop to read the file backward while printing the results in the original sequence. Look at the script for better understanding:
#!/bin/bash
filename="file.txt"
lines=()
while IFS= read -r line
do
lines+=("$line")
done < <(tac "$filename")
for ((n=${#lines[@]}-1; n>=0; n--))
do
echo "${lines[$n]}"
done
The script starts by assigning “file.txt” to a variable filename. lines=()
initializes an array to store the lines read from the file.txt. while IFS= read -r line
starts a while loop that reads the line from the output of the tac "$filename"
(reverses the lines of the file). lines+=("$line")
appends each line to the lines array.
done < <(tac "$filename")
uses process substitution <(...)
to treat the output of tac "$filename"
as a file and then redirects that output to the standard input of the while loop.
After that, a for
loop is initialized to iterate through the lines array in reverse order. Finally, echo "${lines[$n]}"
prints each line to the terminal in its original order.
You can see all the lines from the file.txt in the original order but it is read in the reverse order.
Common Issues in Bash File Reading With “while” Loop
When reading a file line by line, you can come across certain common issues, such as handling special characters or empty lines. The solutions to these issues are covered in this section.
Dealing With Empty Lines
A file can contain empty lines and the read
command within a while loop by default can read a file including those empty lines. If you want to skip the empty lines from being read, you can follow the script below:
#!/bin/bash
filename="file.txt"
while IFS= read -r line; do
# Skip empty lines
if [[ -n "$line" ]]; then
# Process non-empty lines
echo "$line"
fi
done < "$filename"
This script will only show the lines with content skipping the empty lines:
Managing Special Characters
By default, the read
command within a while loop can not read backslash character \
. So to preserve the backslashes, you can use the -r
option with the read command inside the while loop. Check method 1 for the bash script to manage special characters like \.
Practice Tasks on How to Read File Line Using Bash “while” Loop
Do the following tasks to sharpen your understanding of how to read a file line using a while loop:
- Make a bash script that displays each read line of the “file.txt” along with its line numbers.
- Write a bash script that reads the “file.txt” and prints only the non-empty lines.
- Create a file that contains the names of 7 days of the week. Now, read the names of the file using a while loop.
- Generate a bash script that prints only the file line containing a specific keyword.
- Take a file of your choice, count the number of lines present in that file, and print it in the terminal using bash while loop.
Conclusion
To sum up, I have finished discussing the 8 cases for using a while loop to read a file line by line. Each technique is explained in detail in the demonstration above. I hope this has improved your understanding of using a while loop in various ways to read file data. Have a great day!
People Also Ask
How to skip empty lines or lines starting with specific characters?
You can use an if
conditional statement inside the while loop to skip empty lines or lines starting with specific characters. Here’s an example bash script for this:
while read line; do
if [[ -n "$line" && ! "$line" =~ ^@ ]]; then
# process non-empty lines not starting with @
fi
done < file.txt
While reading file lines, this script skips the empty lines and lines containing the specific character “@” of the “file.txt”.
How does the while loop read a file line by line in Bash?
The while loop reads a file line by line in Bash using the read
command. Check out the basic syntax for this task:
while IFS= read -r line; do
# Process the current line here
done < "filename"
This script reads a file preserving leading and trailing whitespaces and backslash characters.
How to exit the loop early based on a condition?
To break a while loop early based on a condition, you can use a break
statement inside the condition. Here’s an example bash script for this:
while read line; do
if [[ "$line" == "STOP" ]]; then
break
fi
# process lines
done < file.txt
The script exits the loop when the word “STOP” appears on a line while it is reading the lines from the “file.txt”.
What is read command in Bash?
In Bash, a read
command is a powerful tool to read input from a user or a file. It can be used to read a file line by line.
Related Articles
- “while true” Loop in Bash [4 Cases]
- 8 Examples of “while” Loop in Bash
- How to Increment Number Using Bash “while” Loop [8 Methods]
- One Line Infinite “while” Loop in Bash [4 Examples]
- How to Use Bash Continue with “while” Loop [7 Examples]
- Exit “while” Loop Using “break” Statement in Bash [11 Examples]
- How to Use Bash One Line “while” Loop [8 Examples]
- How to Use “sleep” Command in Bash “while” Loop [6 Examples]
<< Go Back to “while” Loop in Bash | Loops in Bash | Bash Scripting Tutorial
FUNDAMENTALS A Complete Guide for Beginners
Hello,
Thank you very much for these very clear explanations.
They saved me from writing a script where the commands/scripts executed inside the loop consumed the standard input (STDIN).
It helped me understand how to use a file descriptor in a while loop.
Regards.