1

I am trying to search for a "pattern 1" only in files that contain another string "pattern 2"

E.g.

A.txt Pattern 1 ... Pattern 2

B.txt Pattern Z ... Pattern 2

I intend to filter out files that match Pattern 1 in this case A.txt and then search occurrences of Pattern 2 only in A.txt.

I am trying below but doesn't work.

grep -rl "Pattern 1" . -exec grep -or "Pattern 2" +

Note: Some file paths include spaces.

1 Answers1

1

You can pipe to xargs:

grep -rlZ "Pattern 1" | xargs -0 grep -l "Pattern 2"

or use find and grep -q + grep -l:

find . -type f \
  -exec grep -q "Pattern 1" {} \; \
  -exec grep -l "Pattern 2" {} +

The xargs option is probably more performant, as it will call grep on multiple files at once, while the find will call grep for each file.

pLumo
  • 22,565
  • 1
    For the find variant, you can use -exec grep -l 'Pattern 2' {} + (and remove -print) to avoid some of the execs. – Kusalananda Jul 15 '19 at 11:00
  • thanks, I was trying it, but only with first grep, that did not work ... but won't the first grep separate the files already ? – pLumo Jul 15 '19 at 11:06
  • 1
    Ah, no, that would not work as that grep has to be run as an individual test on each file. The second one can run on all that passes the first test in one go though. – Kusalananda Jul 15 '19 at 11:08
  • See also https://unix.stackexchange.com/questions/466101/grepping-files-for-multiple-strings-not-on-the-same-line for a form of an "and grep" for all files in a directory. – drl Jul 15 '19 at 12:33