7

I am trying to use find/grep to find some text patterns in my code base. I want to exclude non-source directories into which my build process duplicates source files:

find . -name *.java -not -name *target* -exec grep -l 'someText' {} \; 2>/dev/null

Unfortunately, I still get target directories in the result, e.g.:

./toplevel/src/com/domain/toplevel/module/SourceFile.java

What am I doing wrong and how do I fix it?

5
  • 2
    You've got to quote your patterns. SourceFile.java doesn't contain target AFAICT. Commented Feb 6, 2014 at 22:29
  • doesn't work with quotes either
    – amphibient
    Commented Feb 6, 2014 at 22:30
  • 1
    *.java should be "*.java" without quotes -name interprets your argument as literal expression
    – Kiwy
    Commented Feb 6, 2014 at 22:32
  • didn't change anything when i tried
    – amphibient
    Commented Feb 6, 2014 at 22:33
  • 1
    It would if you had any .java files in your current directory.
    – terdon
    Commented Feb 6, 2014 at 22:37

1 Answer 1

8

-name pattern matches on the file name. SourceFile.java doesn't match *pattern*, so it is included. If you want not to descend into directories whose name contains target, then you'd need:

find . -name '*target*' -prune -o -name '*.java' \
  -exec grep -sl 'someText' {} +

(remember to quote patterns, otherwise they can be expanded by the shell).

For several patterns:

find . \( -name 'pattern1' -o -name 'pattern2' \) -prune \
  -o -name '*.java' -exec grep -sl 'someText' {} +

(AND (-a) is implied when not specified between two predicates. AND has precedence over OR (-o), hence the brackets above).

Note that ! is the portable/standard equivalent of -not.

If you want to match on the full path, then you need to use -path instead like:

find . -name '*.java' ! -path '*target*' -exec grep -sl someText {} +

But that's not stopping find from descending into *target* directories, which is a bit of a waste since find won't report any file in there.

1
  • very good. however, in the real life example, I would like to exclude more patterns than just target. when i tried find . -name '*target*' -name '*otherPattern*' -prune ..., it didn't work
    – amphibient
    Commented Feb 6, 2014 at 22:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .