Grep 2 Lines using `grep` Command in Linux

grep is excellent to match patterns from STDOUT/text files in command line or scripts. It’s handy. Sometimes, our problem is more complex than finding a keyword from a file. On a first thought, it may sound impossible using grep for such complex problems. But grep can be quite powerful than we thought. Today, let’s check one example.

The problem to grep

The problem is as follows. We want to check whether the ~/.bashrc file contains 2 consecutive lines (okay to assume they are not at the beginning of the file):

export GOPATH=$HOME/go
export PATH=$GOPATH/bin:$PATH

There are 2 criteria: 1. these 2 lines must both exist, and 2. these 2 lines are consecutive.

The difficulties with grep

Right, the basic pattern format by grep has difficulties to understand the \n (new line) as the input is matched line by line. But we don’t need to stop here. grep has many options. The key is to make it match \n. First, we need to make grep not use \n as the line separator. Second, we need to make grep treat \n as a normal character.

The solution

For the first purpose, the -z option is useful. It makes grep “treat input and output data as sequences of lines, each terminated by a zero byte (the ASCII NUL character) instead of a newline.”. For the second purpose, the -P option is useful. It makes grep use Perl-compatible regular expression (PCRE) grammar which can treat \n as a normal character.

With all these analysis, we can build the command now:

grep -Pzl '\nexport GOPATH=\$HOME/go\nexport PATH=\$GOPATH/bin:\$PATH\n' \
~/.bashrc

The first \n make sure the first line start after a \n. The last \n makes sure the second line is in a single line instead of a head of a longer line. \$ is used because $ in PCRE is a special character.

The same technique can be used for perl one-liners too: How to Match Multiple Lines using Regex in Perl One-liners.

Eric Ma

Eric is a systems guy. Eric is interested in building high-performance and scalable distributed systems and related technologies. The views or opinions expressed here are solely Eric's own and do not necessarily represent those of any third parties.

Leave a Reply

Your email address will not be published. Required fields are marked *