Grep - Print N Lines Before and After Match: Unix Command

1. Grep Overview

In this tutorial, We'll learn how to print before and after grep command results content for each match in UNIX.

In my work some days back, I was using a UNIX grep command on the log file. My job is to find the exceptions in the log file and get the complete exception stack trace. But when we do the following command returns only the line that matches the Exception word.

grep 'Exception' apllication.log


After doing research on grep command, found useful flags that are very helpful. Before that just see the useful use case.

Print Before and After Lines Using Grep



2. Sample application.log file


The below provides is a just a example application log file. This application processes the trade transactions for every business day and processing is done batch by batch. Each batch takes 100 messages for processing. Take a look at this log file for our demo.

Application Started.
Processing 100 trade messages for business date : 2019-12-12
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 12 out of bounds for length 0
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:372)
at java.base/java.util.ArrayList.get(ArrayList.java:458)
at com.java.w3schools.blog.core.exceptin.ApplicationProcess.main(ApplicationProcess.java:11)

Processing batch 2 - 100 trade messages for business date : 2019-12-12
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.java.w3schools.blog.core.exceptin.ApplicationProcess.main(ApplicationProcess.java:11)
Processing batch 3 - 100 trade messages for business date : 2019-12-12
Processing batch 3 - Completed
Processing batch 4 - 100 trade messages for business date : 2019-12-12
Exception in thread "main" com.java.w3schools.blog.core.exceptin.ServiceDownException: Manager Service is down. Please restart the Service.
at com.java.w3schools.blog.core.exceptin.ApplicationProcess.main(ApplicationProcess.java:11)
There are several batches failure. These will be reprocessed in next run.


Output:

Ran the grep command on the this file and produced the following output.

$ grep 'Exception' application.log
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 12 out of bounds for length 0
Exception in thread "main" java.lang.ArithmeticException: / by zero
Exception in thread "main" com.java.w3schools.blog.core.exceptin.ServiceDownException: Manager Service is down. Please restart the Service

But, this is not much helpful just giving the error reason. We should find the the exact location of the file problem occurs. This information sits in next few lines after the exception.

My friends also asked me many times How did I fetch lines before/after the grep result in bash? I will show you the solution in a few minutes. It is very simple.

Some more colleagues asked, How did you manage this manually getting after the exception lines or is there way to show lines before and after the match in Linux?

I told them, always do some research before doing manually anything.

Found the useful and hand flags with Grep.

3. Grep Command Parameters:


Parameter for grep to show lines before and after the found line.


-A number of lines to show after every match
-B number of lines to show before every match
-C numbers of lines to show before and after every match(with default of 2).

4. Example Grep Commands


Printing 6 lines after match with 'java.lang.IndexOutOfBoundsException'

$ grep -A 6 'java.lang.IndexOutOfBoundsException' application.log
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 12 out of bounds for length 0
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:372)
at java.base/java.util.ArrayList.get(ArrayList.java:458)
at com.java.w3schools.blog.core.exceptin.ApplicationProcess.main(ApplicationProcess.java:11)

printing 1 extra line after every match with word 'Exception'

$ grep -A 1 'Exception' application.log
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 12 out of bounds for length 0
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
--
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.java.w3schools.blog.core.exceptin.ApplicationProcess.main(ApplicationProcess.java:11)
--
Exception in thread "main" com.java.w3schools.blog.core.exceptin.ServiceDownException: Manager Service is down. Please restart the Service.
at com.java.w3schools.blog.core.exceptin.ApplicationProcess.main(ApplicationProcess.java:11)

All matches are separated by a double hyphen "--".

We can use -B to see the lines before each match.

grep -B 3 'Exception' application.log


This command prints 3 lines before match.

Use -C to show surrounding lines for each match (Before and After match)

grep -C 1 'Exception' application.log


Prints 1 lines before and after every match.

5. Conclusion


In this article, We've learned how to print the surrounding lines when grep a file. Options are -A for After, -B for Before and -C for before & after each match.

Typically grep is an efficient way to search text. However, it can be quite slow in some cases, and it can search for large files where even minor performance tweaking can help significantly.

Grep Reference
Grep After Match
Ma Ref
Stackoverflow

0 Comments