How to use grep for 2 different lines
How can I search for two different phrases when they are on two different lines by using a single grep
command?
For example
Line 1: This is a sweet.
Line 2: lemon.
I used this but no result
grep "sweet.*lemon" file_type
To use grep
for two different lines, search for both patterns
$ grep -e sweet -e lemon file_type
This is a sweet
lemon.
Or use alternation
$ grep -E 'sweet|lemon' file_type
This is a sweet
lemon.
To get the next line after a pattern, you could use the context option
$ grep -A1 sweet file_type
This is a sweet
lemon.
But if you're searching explicitly for a multiline pattern, that's tricky because grep
thinks in lines.... Your .*
will catch everything between "sweet" and "lemon" on the line. We can get "lemon" on the next line with -P
using \n
to match the newline and by telling grep
the file is null separated with -z
:
$ grep -zPo 'This is a sweet\nlemon' file_type
This is a sweet
lemon.
Notes:
-
-E
Use extended regular expressions (to use|
character for alternation without needing to escape it) -
-An
Print additional lines after the pattern, where n is the number of trailing lines to print -
-P
Use perl-style regular expressions ("experimental" ingrep
- installpcregrep
instead for better perl regex support) -
-z
Use the null character as separator (just pretending in this case, butgrep
will take our word for it) -
-o
only print the matched part
Like this:
grep "sweet\|lemon"
Here is a pretty robust method for teasing out two lines which appear adjacent. I've laid it out so that the line order does not matter, but if it does matter this can be easily adjusted.
First I created a file with lines:
dog
fish
elephant
wombat
cat
pickle
anglepoise lamp
Then I performed the following tests to demonstrate a use of grep including -A and -B to tease out just the two lines in question.
2020-08-14 02:08:45 → touch Desktop/test/file.txt
2020-08-14 10:01:03 → grep -A1 -B1 cat Desktop/test/file.txt
wombat
cat
pickle
2020-08-14 10:01:10 → grep -A1 -B1 cat Desktop/test/file.txt | grep -A1 -B1 wombat
wombat
cat
2020-08-14 10:01:27 → grep -A1 -B1 cat Desktop/test/file.txt | grep -A1 -B1 pickle
cat
pickle
2020-08-14 10:01:49 →
What's going on? First A and B mean after and before. So we are grepping for our term (cat) and including in the response one line after and one line before our target line. This will yield two or three lines depending if the target line is a first or last line (2 lines) or if the target line is somewhere else in the file. (A file with a single line can only return one line, obviously.)
Then we grep those results using the same method with the second search term. This will cut the three lines from above to two lines unless both terms happen to appear on the same line.