Bash is one of the most popular and poweful shell interpreters in Linux and other Unix-based systems. It comes packed with a wide variety of tools and features for simple automation to complex scripts.

One of the most common tasks in scripting that you might come across is reading files. Specifically, reading files line by line. For example, you might need to parse logs, or read data from a hidden file.

Lucky for us, Bash offers some very cool features and tools that we can use to read files line by line.

Method 1 - Using While Loop

One of the most straightforward ways to read a file line by line in Bash is by using a while loop. This method is simple and efficient for small to medium-sized files.

Suppose we have a file called server.log, we can read it line by line using a while loop as shown:

#!/bin/bash
file_path="server.log"

# Check if the file exists
if [ ! -f "$file_path" ]; then
    echo "File not found: $file_path"
    exit 1
fi

# Read the file line by line using a while loop
while IFS= read -r line; do
    echo "Line: $line"
done < "$file_path"

In the example script above, we start by invoking a while loop that reads each line from the specified file path.

We also set the Internal Field Seperator to an empty string to ensure that we preserve any leading or trailing whitepsace characters.

NOTE: We also use the -r option in the read command to prevent backslashes from escaping characters.

Method 2 - Using Read without While Loop

We can also remove the while loop and just take advantage of the read command to recursively read a file line by line.

Take for example the script shown below:

file_path="server.log"
# Check if the file exists
if [ ! -f "$file_path" ]; then
    echo "File not found: $file_path"
    exit 1
fi
# Read and process each line in a loop
while read -r line; do
    echo "Line: $line"
done < "$file_path"

You will notice that this technique is pretty similar to the while loop only without the loop.

Method 3 - Using mapfile (Bash 4.0+)

Starting from Bash version 4.0, we can use the mapfile command to read lines from a file into an array. This method is especially useful for large files as it is more memory-efficient compared to using while loops.

#!/bin/bash

file_path="server.log"

# Check if the file exists
if [ ! -f "$file_path" ]; then
    echo "File not found: $file_path"
    exit 1
fi

# Read the file into an array using mapfile
mapfile -t lines < "$file_path"

# Process each line in the array
for line in "${lines[@]}"; do
    echo "Line: $line"
done

In this case, we use the mapfile command to read the file into the lines array. We can then access each line as an element of the array.

Method 4 - Using sed Command

We can also use the sed (stream editor) utility to read a file line by line and perform text processing as shown in the example below:

#!/bin/bash
file_path="server.log"

# Check if the file exists
if [ ! -f "$file_path" ]; then
    echo "File not found: $file_path"
    exit 1
fi

# Read the file line by line using sed
sed 's/^/Line: /' "$file_path"

This should basically read the file line by line and append the string Line: to each entry.

Method 5 - Using awk Command

As you can guess, where there is sed, awk can work as well.

Since awk is very versatile when it comes to text processing, we can use it to read files line by line and perform various operations on them.

The following shows how to do just that while printing the contents of the file.

file_path="example.txt"

# Check if the file exists
if [ ! -f "$file_path" ]; then
    echo "File not found: $file_path"
    exit 1
fi

# Read the file line by line using awk
awk '{print "Line:", $0}' "$file_path"

In this script, awk processes each line and prints it with a prefix "Line: ".

Conclusion

Reading files line by line in Bash is a fundamental task when working with text files. In this guide, we've explored various methods and techniques, ranging from simple while loops and read commands to more advanced tools like mapfile.

Great! Next, complete checkout for full access to GeekBits.
Welcome back! You've successfully signed in.
You've successfully subscribed to GeekBits.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info has been updated.
Your billing was not updated.