I want to exclude some directories from searching files and than run the find command to find required files. I am using below command

find . -maxdepth 1 -type d | grep -E -i 'sensors' | grep -v '.test' | xargs find -name '*.java'

But it throws following error

find: paths must precede expression

3 Answers 3


The first find will cause the second find to list everything twice unless you exclude the current directory as well. This happens because the output of the first find contains a period.

$ find -maxdepth 1 -type d -print0 |
   grep -z -v -Ee 'sensors|\.test' |
   xargs.exe -0 -I% find % -name '*.java' |

You're better off doing something like this instead:

$ find . -type f -name \*java | grep -v -Ee './(sensors|\.test)'

Or even:

$ echo dirz foo moo | tr \  \\n  > .search-dirs

$ find `cat .search-dirs` -type f -name \*java

Use xargs' -i option which like in find's -exec option replaces {} with the paths.

... | xargs -i find "{}" -name '*.java'

You can do it directly in find; no need to involve grep or xargs.

With a directory structure like:

$ ls *
my_file.java  my_non_java_file.txt

my_file.java  my_non_java_file.txt

my_file.java  my_non_java_file.txt

, this GNU find command will pick out files ending in .java in directories in the current working directory that contain the word sensors, but does not end in .test (if I interpreted your question correctly):

$ find -type f -ipath './*sensors*' -not -ipath './*.test/*' -iname '*.java'

man find should explain the switches clearly and probably better than I would.

Piping is powerful, but the base tools handle many scenarios by themselves in a more straightforward manner. This avoids unnecessary process forks and keeps subtle errors to a minimum.

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.