Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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 :)

share|improve this question
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 '11 at 15:47
up vote 3 down vote accepted
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.

share|improve this answer
This is awfully complicated. See Kevin's answer. – Gilles Dec 16 '11 at 7:49
@Gilles yes I agree with you. I have +1 his answer. – Sachin Divekar Dec 16 '11 at 8:40
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... – don_crissti Oct 2 '15 at 11:46

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 .
share|improve this answer
which find should work? – cwd Dec 14 '11 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 '11 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. – Rich Homolka Apr 29 at 2:43

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.

share|improve this answer
That one has the benefit of being standard and portable. – Stéphane Chazelas Oct 2 '15 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. – Stéphane Chazelas Oct 2 '15 at 12:45

You find not matching result by option -L

grep -iL shared.php .
share|improve this answer

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.

share|improve this answer
No, this doesn't work as you think... it prints the names of all files that contain at least one line not matching the pattern (that is, even files that also contain line(s) matching pattern). – don_crissti Oct 2 '15 at 11:27

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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