Print Lines Between Two Patterns in Linux


Printing lines between two patterns is functional when you need to print only a few lines from these files or keep your lines under a specific pattern.

Although you can print the lines through the grep command, it is impossible to print the particular line. In this case, you can use commands like sed or awk to print lines between two patterns.

So In this article, we will elaborate on various examples to print lines between two patterns in Linux. We will also include multiple conditions for using the sed and awk command to print lines between patterns.

Printing Lines Between Two Patterns in Linux

First, we will create an example.txt file that contains the following content −

:~$ cat example.txt
Information Start
Professional Details: 
Name: John Novik
Occupation: Technical Writer
Salary: 250K/Year
Company Name: Tutorialspoint 
Information End

Information Start
Personal Details: 
Address: House No. XX Street 254/76 
Age: 26 Years
Information End

As you can see in the above output, this file has two sections, 'Information Start' and 'Information End.' So let's print lines between these two patterns using the sed and awk command differently.

The Sed Command

The sed command provides several options for making changes or modifications only to the selected lines and selecting the lines to be modified. As per the edited script, this command modifies the lines from the specified file parameter and shows them as output.

Condition 1: Print the Lines Excluding the Both Patterns

Since the sed command does not support logical operators, you cannot fulfill the above condition by joining the patterns and the AND operator. However, we can do this by nesting two checks instead of the AND operator.

:~$ sed -n '/pattern 1/, /pattern 2/{ /pattern 1/! { /pattern 2/! p } }' <filename>

Note − As you can see, in all the above conditions, we have used the '-n' and 'p' options, which means,

  • -n − To prevent printing the pattern space.

  • p − To control the output.

For example, let's exclude 'Information Start' and 'Information End' to print the rest of the information from the example.txt file −

:~$ sed -n '/Information Start/, /'Information End/{ /Professional Details/! { /'Personal Details/! p } }' example.txt
Information Start
Professional Details: 
Name: John Novik
Occupation: Technical Writer
Salary: 250K/Year
Company Name: Tutorialspoint 
Information End

Information Start
Personal Details: 
Address: House No. XX Street 254/76 
Age: 26 Years
Information End

Condition 2: Print the Lines Including the One Pattern Only

You can remove lines matching a pattern by doing another check on the lines in the address range. The command would be something like this −

:~$ sed -n '/pattern 1/, /pattern 2/{ /pattern 2/!p }' <filename>

In this condition, we must keep only one pattern and remove or suppress the other one. We will print the lines from the above file between the 'Information Start' pattern by removing the 'Information End' pattern.

:~$ sed -n '/Information Start/, /Information End/{ /Information Start/!p }' example.txt
Professional Details: 
Name: John Novik
Occupation: Technical Writer
Salary: 250K/Year
Company Name: Tutorialspoint 

Personal Details: 
Address: House No. XX Street 254/76 
Age: 26 Years

Condition 3: Print the Lines Between the Both Pattern

Including both patterns in the file and printing the lines between them are easy. So use the following sed command to do this −

:~$ sed -n '/pattern 1/, /pattern 2/p' <filename>

Here we include both the pattern, 'Information Start' and 'Personal Details' using the following command −

:~$ sed -n '/Information Start/, /Information End/p' example.txt
Information Start
Professional Details: 
Name: John Novik
Occupation: Technical Writer
Salary: 250K/Year
Company Name: Tutorialspoint 
Information End

Information Start
Personal Details: 
Address: House No. XX Street 254/76 
Age: 26 Years 
Information End

The Awk Command

The awk command is a perfect alternative to the sed command when your requirements are complex. This command has various options to filter the pattern processing and scanning results. You can replace and search the sorts and texts, index the database, and validate with the sed command, as it provides good data control.

Condition 1: Print the Lines Between the Both Pattern

Like the sed command, you can print the lines between two patterns using the awk command. To do this, use the following command −

:~$ awk '/pattern 1/, /pattern 2/' <filename>

Using the awk command here, we include both patterns (Information Start, Information End) as follows −

:~$ awk '/Information Start/, /Information End/' example.txt
Information Start
Professional Details: 
Name: John Novik
Occupation: Technical Writer
Salary: 250K/Year
Company Name: Tutorialspoint 
Information End

Information Start
Personal Details: 
Address: House No. XX Street 254/76 
Age: 26 Years
Information End

If your variable has a non-zero value, this command evaluates this variable as True as well. So you can also declare a variable to turn off or on printing under different conditions as follows −

:~$ awk '/pattern 1/{ f = 1 } f; /pattern 2/{ f = 0 }' <filename> 

For example, we declare the variable for including both of the patterns using the following command −

:~$ awk '/Information Start/{ f = 1 } f; /Information End/{ f = 0 }' example.txt
Information Start
Professional Details: 
Name: John Novik
Occupation: Technical Writer
Salary: 250K/Year
Company Name: Tutorialspoint 
Information End

Information Start
Personal Details: 
Address: House No. XX Street 254/76 
Age: 26 Years 
Information End

Instead of using the range pattern, we have declared a variable 'f' as a switch for the awk printer in the above command.

  • When pattern 1 is matched, we turn it on and print its range by 'f.'

  • When f is turned on, it prints all lines until pattern 2 is reached.

  • Till pattern 2, the value of f is kept as 1 because it is also to be printed, and after it comes, we turn off the switch by setting the value of f to 0.

  • Thus you can use the 'printer switch' to solve the problem in other scenarios.

Condition 2: Print the Lines Excluding the Both Patterns

Use the following command to remove both patterns under the output −

:~$ awk '/pattern 1/{ f = 1; next } /pattern 2/{ f = 0 } f' <filename>

This command is tricky because when pattern 1 starts, the output has to be turned on, and immediately after that, the following action is executed { f = 1; next }. Where we stop processing the current line and read the next line from the input. Thus the switch is kept on, but pattern 1 is not printed. We exclude both patterns by running the below awk command −

:~$ awk '/Information Start/{ f = 1; next } /Information End/{ f = 0 } f' example.txt
Information Start
Professional Details:
Name: John Novik
Occupation: Technical Writer
Salary: 250K/Year
Company Name: Tutorialspoint 
Information End

Information Start
Personal Details:
Address: House No. XX Street 254/76 
Age: 26 Years 
Information End

Condition 3: Print the Lines Including the Pattern 2 Only

If f is placed before pattern 1, the lines of pattern 1 are not printed in the output.

:~$ awk 'f; /pattern 1/{ f = 1 } /pattern 2/{ f = 0 }' <filename>

When using a variable in awk, its value will be 0 or the empty string if it is not previously assigned or declared. Additionally, the variable will only be evaluated as false, so the default print system is not triggered.

Here, we only print the lines between the 'Information End' pattern. For this, we use the following command −

:~$  awk 'f; /Information Start/{ f = 1 } /Information End/{ f = 0 }' example.txt
Professional Details:
Name: John Novik
Occupation: Technical Writer
Salary: 250K/Year
Company Name: Tutorialspoint 
Information End

Personal Details:
Address: House No. XX Street 254/76 
Age: 26 Years 
Information End

Condition 4: Print the Lines Including the Pattern 1 Only

In this condition, we have changed the command to include pattern 1, which is something like this −

:~$ awk '/pattern 1/{ f = 1 } /pattern 2/{ f = 0 } f' <filename>

As you can see, we have changed the position of f in the above command. When F is placed at the end, the switch is closed as soon as pattern 2 comes. Then the output is printed by checking the switch so that the lines of pattern 2 are not printed.

Therefore, we print the lines between the 'Information Start' pattern only using the below awk command −

:~$  awk '/Information Start/{ f = 1 } /Information End/{ f = 0 } f' example.txt
Information Start
Professional Details:
Name: John Novik
Occupation: Technical Writer
Salary: 250K/Year
Company Name: Tutorialspoint 

Information Start
Personal Details:
Address: House No. XX Street 254/76 
Age: 26 Years

Condition 5: Print Lines Between the Specific Range of Lines

Using the below awk command, you can define a range of specific lines and print only those lines.

:~$  awk 'NR==X, NR==Y' <filename>

Here X will be the starting range of printing lines, and Y will be the end range, and it will print all the lines between these lines. For example, we print the lines from line 5 to line 11 from the example.txt file.

:~$ awk 'NR==5, NR==11' example.txt
Information End
Information Start
Personal Details:
Address: House No. XX Street 254/76 
Age: 26 Years 
Information End

Conclusion

In this article, we have explained how to print lines and text between patterns. In Linux, you can print lines between the patterns through the sed and awk command utilities. We have described various examples and conditions for printing only specific lines from a file. Remember to use every command carefully, or you will get improper information from the selected file.

Updated on: 18-May-2023

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements