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,231
  • 2
  • 41
  • 66
  • 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