Grep 2 Lines using `grep` Command in Linux
Posted on In Linux, Tutorialgrep
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.
Table of Contents
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.