Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I would like to get the multi pattern match with implicit AND between patterns, i.e. equivalent to running several greps in a sequence:

grep pattern1 | grep pattern2 | ...

So how to convert it to something like?

grep pattern1 & pattern2 & pattern3

I would like to use single grep because I am building arguments dynamically, so everything has to fit in one string. Using filter is system feature, not grep, so it is not an argument for it.

Don't confuse this question with:

grep "pattern1\|pattern2\|..."

This is an OR multi pattern match.

share|improve this question
up vote 27 down vote accepted

agrep can do it with this syntax:

agrep 'pattern1;pattern2'

With GNU grep, when built with PCRE support, you can do:

grep -P '^(?=.*pattern1)(?=.*pattern2)'

With ast grep:

grep -A '.*pattern1.*&.*pattern2.*'

(adding .*s as <x>&<y> matches strings that match both <x> and <y> exactly, a&b would never match as there's no such string that can be both a and b at the same time).

If the patterns don't overlap, you may also be able to do:

grep -e 'pattern1.*pattern2' -e 'pattern2.*pattern1'

The best portable way is probably with awk as already mentioned:

awk '/pattern1/ && /pattern2/'

With sed:

sed -e '/pattern1/!d' -e '/pattern2/!d'

Please beware that all those will have different regular expression syntax.

share|improve this answer
Thank you for grep examples! Marking as accepted. – greenoldman Nov 13 '12 at 19:30

You didn't specify grep version, this is important. Some regexp engines allow multiple matching groupped by AND using '&' but this is non-standard and non-portable feature. But, at least GNU grep doesn't support this.

OTOH you can simply replace grep with sed, awk, perl, etc. (listed in order of weight increasing). With awk, the command would look like

awk '/regexp1/ && /regexp2/ && /regexp3/ { print; }'

and it can be constructed to be specified in command line in easy way.

share|improve this answer
Just remember that awk uses ERE's, e.g. the equivalent of grep -E, as opposed to the BRE's that plain grep uses. – jw013 Nov 10 '12 at 9:42
awk's regexes are called EREs, but in fact they're a bit idiosyncratic. Here are probably more details than anyone cares for: wiki.alpinelinux.org/wiki/Regex – dubiousjim Nov 10 '12 at 15:35
Thank you, grep 2.7.3 (openSUSE). I upvoted you, but I will keep question open for a while, maybe there is some trick for grep (not that I dislike awk -- simply knowing more is better). – greenoldman Nov 10 '12 at 15:42

If patterns.txt contains one pattern per line, you can do something like this:

awk 'NR==FNR{a[$0];next}{for(i in a)if(!match($0,i))next}1' patterns.txt -

To search for fixed strings instead of regular expressions, replace match with index.

To print all instead of no lines of the input in the case that patterns.txt is empty, replace NR==FNR with FILENAME==ARGV[1] or with ARGIND==1 in gawk.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.