What concise command can I use to find all files that do NOT contain a text string?

I tried this (using -v to invert grep's parameters) with no luck:

find . -exec grep -v -l shared.php {} \;

Someone said this would work:

find . ! -exec grep -l shared.php {} \;

But it does not seem to work for me.

This page has this example:

find ./logs -size +1c  > t._tmp
while read filename
     grep -q "Process Complete" $filename
     if [ $? -ne 0 ] ; then
             echo $filename
done < t._tmp
rm -f t_tmp

But that's cumbersome and not at all concise.

ps: I know that grep -L * will do this, but how can I use the find command in combination with grep to excluded files is what I really want to know.

pss: Also I'm not sure how to have grep include subdirectories with the grep -L * syntax, but I still want to know how to use it with find :)

  • 1
    The first command you wrote worked fine on my computer. What version of find are you using? And since we're at it, maybe specify which unix you're running..
    – rahmu
    Dec 14, 2011 at 15:47
  • @rahmu, this command almost always does not work as you expect. You probably have had a very specific case. Please see unix.stackexchange.com/questions/339619/…
    – sgnsajgon
    Jun 17, 2017 at 19:31

5 Answers 5


Your find should work if you change -v -l (files that have any line not matching) to -L (files with no lines matching), but you could also use grep's recursive (-r) option:

grep -rL shared.php .
  • which find should work?
    – cwd
    Dec 14, 2011 at 15:13
  • @Kevin - sorry, find . -exec grep -v -l shared.php {} \; (and all the other variants I tried) is not working for me. I'm on OS X but I don't think that should matter. I gave you a +1 because I had forgotten about the -r option.
    – cwd
    Dec 14, 2011 at 15:49
  • @cwd i know this is old but i want to leave this here for future readers: the fact that you're on OS X does make a difference. Mac OSX uses FreeBSD commands. Most people here assume Linux (GNU) style commands. They have different arguments, different ways of handling details. Apr 29, 2016 at 2:43
  • As of 2016 OSX does appear to support -L Mar 8, 2017 at 0:14
  • @kevin I said it does, not that it doesn't. :) not that anyone explicitly said it didn't, but the comments were confusing (and I've certainly run into other OS X / BSD vs GNU issues). Mar 8, 2017 at 4:58
find . -type f | xargs grep -H -c 'shared.php' | grep 0$ | cut -d':' -f1    


find . -type f -exec grep -H -c 'shared.php' {} \; | grep 0$ | cut -d':' -f1

Here we are calculating number of matching lines(using -c) in a file if the count is 0 then its the required file, so we cut the first column i.e. filename from the output.

  • 7
    This is awfully complicated. See Kevin's answer. Dec 16, 2011 at 7:49
  • @Gilles yes I agree with you. I have +1 his answer. Dec 16, 2011 at 8:40
  • 7
    This is not only "awfully complicated" but wrong as it would also list all files that contain a multiple of 10 lines matching the pattern. Even if that grep was fixed this would still assume no file names containing : or newline characters... Oct 2, 2015 at 11:46
  • @don_crissti, thanks for mentioning! Still, unless you use a lot of copy-paste code, the solution above is a rly nice gimmick.
    – Ufos
    Oct 13, 2016 at 16:54
  • @Ufos - I really don't get your comment... This is wrong. Anyway, feel free to use it if it looks like a "really nice gimmick" to you... Oct 13, 2016 at 17:00

I know that grep -L * will do this, but how can I use the find command in combination with grep to exclude files is what I really want to know

You could use find and grep like this:

find . -type f ! -exec grep -q 'PATTERN' {} \; -print

Here -print is executed only if the previous expression: ! -exec ... {} evaluates as true.
So for each file found, grep -q 'PATTERN' is executed, if the result is false then the entire expression ! -exec grep -q 'PATTERN' evaluates as true and the file name is printed.

  • 2
    That one has the benefit of being standard and portable. Oct 2, 2015 at 12:44
  • There's a difference with GNU's grep -L though in that it will also include the non-readable files in the list. Oct 2, 2015 at 12:45

You find not matching result by option -L

grep -iL shared.php .

I think you are looking for a command like

find . -type f -execdir grep -q -v shared.php {} \; -print

The option -q makes grep quit and after using -execdir you need -print to print found files.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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