7

I am looking for a command options for grep to find files with the occurences of foo and bar.

Grepping with

grep -r -e foo -e bar .

shows files which have only foo or only bar and files which have foo and bar.

Is it possible with grep to find only files which have both foo and bar (and display the lines that match either foo or bar or both in those files only)?

Example:

echo foo > file1
echo bar > file2
(echo foo;echo;echo bar) >file3
echo barfoo > file4

the grep cmd:

grepcmd -r -e foo -e bar .
./file3:foo
./file3:bar
./file4:barfoo

1 Answers1

10

to find files that contain both:

(assuming GNU grep/xargs)

grep -rl --null abc . | xargs -r0 grep -l bcd

And if you want to see the lines that contain abc or bcd or both in the files that contain both abc and bcd:

grep -rl --null abc . |
  xargs -r0 grep -l --null bcd |
  xargs -r0 grep -He abc -e bcd

to match lines that contain both:

grep -re 'foo.*bar' -e 'bar.*foo' .

That works as long as the patterns don't overlap.

grep -re 'abc.*bcd' -e 'bcd.*abc' .

Would fail to find the lines that contain abcd.

If your grep has -P for PCRE:

grep -rP '^(?=.*abc).*bcd' .

would work.

Or, POSIXly:

find . ! -type d -exec awk '/abc/ && /bcd/ {print FILENAME ":" $0}' {} +

You could also use agrep:

agrep -r 'abc;bcd' .
  • Nice, thanks! The keywords mustn't be in one line, does grep parse multiple lines? –  Feb 07 '14 at 16:04
  • None of the commands shows two lines. I modified my question again. So if I search for foo and bar, I want to have listed the files and the lines with foo and bar like I'd search for only one string. –  Feb 07 '14 at 19:48
  • @bersch, sorry, I don't understand what you mean, please give an example with expected output. – Stéphane Chazelas Feb 07 '14 at 19:53
  • @StephaneChazelas +1 for agrep, anyways where you find this tool ? – Rahul Patil Feb 07 '14 at 19:58
  • @RahulPatil, it used to come with ht://dig, but you can find it as a separate package now on some distributions. The a is for approximate which is its main feature (one you'd expect from a search engine like htdig). – Stéphane Chazelas Feb 07 '14 at 20:00
  • updated the question, should be now more clear. –  Feb 07 '14 at 21:59
  • @bersch, so how is grep -rl --null abc . | xargs -r0 grep -l --null bcd | xargs -r0 grep -He abc -e bcd not answering the question? (replace abc, bcd with foo, bar)? – Stéphane Chazelas Feb 07 '14 at 22:44
  • @RahulPatil, sorry, not ht://dig, that was glimpse. Bad memory. – Stéphane Chazelas Sep 06 '16 at 05:52