I want to find files that have "abc" AND "efg" in that order, and those two strings are on different lines in that file. Eg: a file with content:
blah blah..
blah blah..
blah abc blah
blah blah..
blah blah..
blah blah..
blah efg blah blah
blah blah..
blah blah..
Should be matched.
If you are willing to use contexts, this could be achieved by typing
This will display everything between "abc" and "efg", as long as they are within 500 lines of each other.
awk one-liner:
This should work:
If there is more than one match you can filter out using grep -v
Grep is not sufficient for this operation.
pcregrep which is found in most of the modern Linux systems can be used as
There is a newer pcre2grep also. Both are provided by the PCRE project.
pcre2grep is available for Mac OS X via Mac Ports as part of port
pcre2
:and via Homebrew as:
or for pcre2
I released a grep alternative a few days ago that does support this directly, either via multiline matching or using conditions - hopefully it is useful for some people searching here. This is what the commands for the example would look like:
Multiline:
sift -lm 'abc.*efg' testfile
Conditions:
sift -l 'abc' testfile --followed-by 'efg'
You could also specify that 'efg' has to follow 'abc' within a certain number of lines:
sift -l 'abc' testfile --followed-within 5:'efg'
You can find more information on sift-tool.org.
This can be done easily by first using
tr
to replace the newlines with some other character:Here, I am using the alarm character,
\a
(ASCII 7) in place of a newline. This is almost never found in your text, andgrep
can match it with a.
, or match it specifically with\a
.