Grep string where next line does not contain string

command linegrepsearchtext processing

I want to search all files inside a directory and its subdirectories for lines containing a certain string, but I want to exclude those results that contain a different certain string in the line immediately after it.

For example, this:

foo1 searchString bar
foo1 excludeString bar

foo2 searchString bar
something else

foo3 searchString bar

foo3 excludeString bar

foo4 searchString bar

should return this:

foo2 searchString bar
foo3 searchString bar
foo4 searchString bar

I know that -A prints multiple lines, and that -v excludes results. But my current approach of grep -r -A 1 "searchString" | grep -v "excludeString" obviously can't work.

Is there a way to tell the second grep that it should also remove the previous line if it finds a match? Or some other way how I might achieve this?

Performance isn't my primary concern; It would be nice if the command is relatively easy to remember though.

Best Answer

You can use perl compatible regular expressions grep:

$ pcregrep -M '(searchString.*\n)(?!.*excludeString)' file
foo2 searchString bar
foo3 searchString bar
foo4 searchString bar

It searches searchString followed by any char ., repeated zero or more times *, followed by new line \n only if there is not (?!) pattern .*excludeString next to it. Option -M is present in order to match multi lines.

Related Question