1. Overview

In this tutorial, we’ll explore how to print the content of a text file and output a blank line after each line in the file using Linux command-line tools.

2. Introduction to the Problem

As usual, let’s understand the problem through an example:

$ cat input.txt 
The website Baeldung.com has articles in many technology areas:

- Java, Spring, Kotlin, Scala
- Linux
- Computer science

It's pretty cool! You should check it out.

We can see the input.txt file contains several lines of text. Further, it includes two empty lines.

If we successfully append one blank line after each line in input.txt, the output should look like this:

The website Baeldung.com has articles in many technology areas:



- Java, Spring, Kotlin, Scala

- Linux

- Computer science



It's pretty cool! You should check it out.

Moreover, this problem may have a variant in practice: skip adding the blank line if the input line itself is empty or it’s the last line. In this case, we expect to have this output:

The website Baeldung.com has articles in many technology areas:

- Java, Spring, Kotlin, Scala

- Linux

- Computer science

It's pretty cool! You should check it out.

In this tutorial, we’ll address how to solve the problem and its variant.

3. Adding a Blank Line After Each Line in the File

We’ll see three ways to add a blank line after each line in the input file.

3.1. The pr Solution

Usually, we use the pr command to paginate text files to make them print-ready. However, we can solve the problem using the pr command with the -d (double space the output) option to add a blank line after each input line. Of course, we don’t want to paginate the input, so we need the -T option additionally to omit pagination:

$ pr -dT input.txt 
The website Baeldung.com has articles in many technology areas:



- Java, Spring, Kotlin, Scala

- Linux

- Computer science



It's pretty cool! You should check it out.

As we can see, we’ve got the desired output.

3.2. The sed Solution

The sed command is good at text processing. It can solve many text-processing problems in pretty compact ways. For example, to solve this problem, we can use a short sed one-liner:

$ sed 'G' input.txt 
The website Baeldung.com has articles in many technology areas:



- Java, Spring, Kotlin, Scala

- Linux

- Computer science



It's pretty cool! You should check it out.

The output above shows the sed one-liner works. Next, let’s understand what magic the ‘G‘ command does.

The sed command manages two workspaces: the hold space and the pattern space. The ‘G‘ command reads the hold space and appends the content to the current pattern space. As we didn’t put any value to the hold space, the default value in the hold space is an empty string with a line break. Therefore, calling ‘G‘ appends a new linebreak to each line.

Further, sed always executes the default action ( ‘p‘ – print the current pattern space) after all the commands have finished execution. Therefore, every line in the input file with an extra linebreak is printed.

3.3. The awk Solution

The awk command is another powerful weapon to process text inputs on the command line. Using awk, we can follow a similar idea to solve the problem – output an extra linebreak after each input line.

So next, let’s see what the awk one-liner looks like:

$ awk '1;{print ""}' input.txt 
The website Baeldung.com has articles in many technology areas:



- Java, Spring, Kotlin, Scala

- Linux

- Computer science



It's pretty cool! You should check it out.

Any nonzero number or not-empty string will be evaluated as the boolean true in awk. Further, a true value will trigger awk‘s default action. Therefore, the ‘1‘ in the awk command above triggers awk‘s default action –  print the current record. Then, {print “”} will output an empty line.

4. Skipping the Blank Lines for Empty Lines and the Last Line

So far, we’ve learned how to output each input line, followed by a blank line in the command line. Now, let’s discuss how to deal with the new requirement of skipping the blank lines for empty input lines and the last line in the input.

The pr command doesn’t provide many customization possibilities to solve different text-processing problems. After all, it’s not a text-processing utility. Therefore, this problem cannot be solved by pr. However, sed and awk are competent for this job. So next, let’s see them in action.

4.1. The sed Solution

We’ve seen sed‘s ‘G‘ command appends a blank line to every input line. We can extend ‘G‘ to handle empty and last lines differently.

First, let’s look at the empty lines’ case. We can use the regex /^$/ to match an empty line. As ‘G‘ will append a linebreak anyway, when an empty line comes, we can simply ignore it: /^$/d.

Further, we still need to deal with the last line. sed‘s address ‘$‘ matches the last input line. Therefore, we can write ‘$ !G‘ to tell sed to execute ‘G‘ on all input lines except the last line.

Now, let’s put them together to see if it works as expected:

$ sed '/^$/d; $ !G' input.txt 
The website Baeldung.com has articles in many technology areas:

- Java, Spring, Kotlin, Scala

- Linux

- Computer science

It's pretty cool! You should check it out.

As we’ve seen in the output, there are no empty trailing lines anymore. Further, the two empty lines are not followed by blank lines either. So, the problem is solved.

4.2. The awk Solution #1

Using awk, we can handle empty lines similarly. However, awk doesn’t have a built-in address to indicate that a line is the last input line. Therefore, we can’t tell awk to do something when the last line comes.

Some may think about the ‘END{…}‘ block. In this case, the ‘END{…}‘ block doesn’t help. This is because it’s executed after the last line is processed.

An example can explain it quickly. Let’s say we want to append the string ” – hello” to each input line except the last line. We may think this command works: awk ‘END{print $0; exit}{print $0 “-hello”};’.

However, if we execute it, we’ll see awk applies {print $0 “-hello”} on each line, including the last line. Then, the END{…} block starts, even though we put it in front of the { print $0 “-hello” } block:

$ seq 3 | awk 'END{print $0; exit}{print $0 "-hello"};' 
1-hello
2-hello
3-hello
3

To achieve our goal, we need to know how many lines are in the input. In this small example, we’ve used seq 3 to feed awk. Therefore, we see the input has three lines. Then we can replace the END with NR==3 to solve it:

$ seq 3 | awk 'NR==3{print $0; exit}{print $0 "-hello"};'    
1-hello
2-hello
3

Of course, we can simplify the command above to seq 3 | awk ‘{print $0 ( NR<3 ? “-hello” : “”)}’.

Now we understand that we need to know the number of lines in the input first. In our real problem, the input is a file. We can use the wc -l command to get the total number of lines in the input file and assign it to an awk variable:

$ awk -v num="$(wc -l < input.txt)" '/^$/{next} 1; NR<num{print ""}' input.txt  
The website Baeldung.com has articles in many technology areas:

- Java, Spring, Kotlin, Scala

- Linux

- Computer science

It's pretty cool! You should check it out.

In the awk command above, we use /^$/{next} to skip the current record if it’s an empty line. It’s pretty similar to sed‘s /^$/d.

It’s worth noting that in the command wc -l < input.txt, we’ve redirected the file to stdin to suppress the filename in wc‘s output:

$ wc -l input.txt 
7 input.txt

$ wc -l < input.txt
7

So, the awk command does the job. But this approach reads the input file twice (by wc and awk).

Next, let’s see if we can solve the problem by walking through the file only once.

4.3. The awk Solution #2

awk supports C-like scripting syntax. Therefore, it’s convenient and flexible if we want to implement some logic.

Since we need to know the total number of lines in the input file and read the file only once, we can first load all input lines into an awk associative array. With the array in hand, we can easily know which element is the last one. So next, let’s see how to do it with awk:

$ awk '{a[NR]=$0} END{ for(i=1;i<=NR;i++) if(a[i]!~/^$/) print a[i] ( i<NR ? RS : "" ) }' input.txt
The website Baeldung.com has articles in many technology areas:

- Java, Spring, Kotlin, Scala

- Linux

- Computer science

It's pretty cool! You should check it out.

As the code above shows, {a[NR]=$0} saves each input line in the ‘a[]‘ array. Then, in the END{ .. } block, we loop through the array and check if the element is empty or the last one to determine the output.

5. Conclusion

In this article, we’ve discussed how to print a blank line after each line in the input file. Further, we’ve analyzed and solved a variant of this problem.

We learned that sed and awk are pretty handy in solving text-processing problems.

Comments are closed on this article!