Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

find negation operator not working as expected

18 views
Skip to first unread message

matt

unread,
Sep 19, 2011, 3:24:31 PM9/19/11
to
I'm trying to find all the files that don't contain a string in the
current directory. This incantation

find . -exec grep -l "foobaz" '{}' \;

will list all the files that contain "foobaz"; however, when I try to
invert this using any one of these incantations

find . ! -exec grep -l "foobaz" '{}' \;
find . \! -exec grep -l "foobaz" '{}' \;
find . -not -exec grep -l "foobaz" '{}' \;

I get the same output. What's going on here?

I'm using a bash shell on darwin Mac OS. The "find" utility I'm using
is the GNU variety built using MacPorts.

Thanks in advance.

Alan Curry

unread,
Sep 19, 2011, 7:20:55 PM9/19/11
to
In article <ee3e5959-ce52-4e7d...@bi2g2000vbb.googlegroups.com>,
matt <matthew...@gmail.com> wrote:
>I'm trying to find all the files that don't contain a string in the
>current directory. This incantation
>
>find . -exec grep -l "foobaz" '{}' \;

grep -l is printing the matching filenames because that's what grep -l does.
find is not printing anything because it doesn't print unless you ask it to
with -print. (In some cases, with a sufficiently new version of find, there
is an implicit -print but this isn't one of those cases.) The -exec does
produce a true/false result based on the exit value of the grep command, but
you're not using that result because the -exec is the last thing in your find
command.

>
>will list all the files that contain "foobaz"; however, when I try to
>invert this using any one of these incantations
>
>find . ! -exec grep -l "foobaz" '{}' \;

Now you've got the same grep command, still printing the same thing it did
before: the matching filenames. find is now getting a true/false result from
the -exec, and inverting it, and then doing nothing with it.

>find . \! -exec grep -l "foobaz" '{}' \;
>find . -not -exec grep -l "foobaz" '{}' \;
>
>I get the same output. What's going on here?
>
>I'm using a bash shell on darwin Mac OS. The "find" utility I'm using
>is the GNU variety built using MacPorts.

If you have GNU grep, then grep -L is what you want. It is the inverse of
grep -l.

If you want to use only minimal standard grep and find features, you need to
do 2 things: make find print the files that failed the -exec, and make grep
just return an exit value without printing anything. That would look like
this:

find . ! -exec grep -q foobaz '{}' \; -print

I'd also stick a -type f on the front, so you don't try to grep a directory.
grepping a directory is Not Good, even if GNU grep fails to complain about
it.

--
Alan Curry
0 new messages