2

I went through the answers on -

  1. Grep regex NOT containing string

  2. http://www.thegeekstuff.com/2011/10/grep-or-and-not-operators/

but I'm still facing some issues to find all the files in a directory which contains "String1" but not "String2".

I tried the following command, but along with the correct result, it also returns the files containing both the strings -

grep -Hrn "String1" . | grep -v -Hrn "String2" 

Kindly correct my mistake.

Community
  • 1
  • 1
Bhavuk Mathur
  • 1,048
  • 1
  • 12
  • 22
  • Cross-site duplicate: http://unix.stackexchange.com/questions/128434/find-files-containing-one-string-but-not-the-other – tripleee Apr 06 '16 at 07:22
  • 1
    Remove the `-Hrn` from your second `grep`: `-r` will make it search recursively in the current dir (basically ignoring your previous `grep`), `-H` will make it show filenames (which it can't do if it's taking input from stdin), and `-n` will make it show line numbers (which will be different in the output of your first `grep`). The first `grep` is correct, and will get the correct filenames and line numbers, but the second `grep` is not. – Score_Under Apr 06 '16 at 07:23

2 Answers2

3

You can use the -L flag:

-L, --files-without-match  print only names of FILEs containing no match

First you find the files that doesn't contain "String2", then you run on those and find the ones that does contain "String1":

$ grep -L "String2" * | xargs grep -nH "String1"
Maroun
  • 94,125
  • 30
  • 188
  • 241
1

This is easy with Awk.

awk 'FNR==1 { if (NR>1 && one && !other) print prev; one=other=0; prev=FILENAME }
    /string1/ { one=1 }
    /string2/ { other=1 }
    END { if (one && !other) print prev }' list of files
tripleee
  • 175,061
  • 34
  • 275
  • 318