Fatih Arslan
Fatih Arslan

Reputation: 17117

Suppress the match itself in grep

Suppose I'have lots of files in the form of

First Line Name
Second Line Surname Adress
Third Line etc
etc

Now I'm using grep to match the first line. But I'm doing this actually to find the second line. The second line is not a pattern that can be matched (it's just depend on the first line). My regex pattern works and the command I'm using is

grep -rHIin pattern . -A 1 -m 1

Now the -A option print the line after a match. The -m option stops after 1 match( because there are other line that matches my pattern, but I'm interested just for the first match, anyway...)

This actually works but the output is like that:

./example_file:1:        First Line Name
./example_file-2-        Second Line Surname Adress

I've read the manual but couldn't fidn any clue or info about that. Now here is the question.

How can I suppress the match itself ? The output should be in the form of:

./example_file-2-        Second Line Surname Adress

Upvotes: 4

Views: 4833

Answers (4)

Amber
Amber

Reputation: 526603

sed to the rescue:

sed -n '2,${p;n;}'

The particular sed command here starts with line 2 of its input and prints every other line. Pipe the output of grep into that and you'll only get the even-numbered lines out of the grep output.

An explanation of the sed command itself:

2,$ - the range of lines from line 2 to the last line of the file

{p;n;} - print the current line, then ignore the next line (this then gets repeated)

(In this special case of all even lines, an alternative way of writing this would be sed -n 'n;p;' since we don't actually need to special-case any leading lines. If you wanted to skip the first 5 lines of the file, this wouldn't be possible, you'd have to use the 6,$ syntax.)

Upvotes: 2

Jeremiah Willcock
Jeremiah Willcock

Reputation: 30969

You can use sed to print the line after each match:

sed -n '/<pattern>/{n;p}' <file>

To get recursion and the file names, you will need something like:

find . -type f -exec sed -n '/<pattern>/{n;s/^/{}:/;p}' \;

Upvotes: 1

If you have already read a book on grep, you could also read a manual on awk, another common Unix tool.

In awk, your task will be solved with a nice simple code. (As for me, I always have to refresh my knowledge of awk's syntax by going to the manual (info awk) when I want to use it.)

Or, you could come up with a solution combining find (to iterate over your files) and grep (to select the lines) and head/tail (to discard for each individual file the lines you don't want). The complication with find is to be able to work with each file individually, discarding a line per file.

Upvotes: 0

Erik
Erik

Reputation: 91270

You could pipe results though grep -v pattern

Upvotes: -1

Related Questions