Coder Perfect

How do I define a recursive search that also detects files in the current directory? “find: paths must precede expression:”

Problem

I’m having trouble getting find to search the current directory and its subdirectories for matches.

When I run find *test.c, it only returns results from the current directory. (doesn’t search subdirectories)

If I run find. -name *test.c, nothing happens. I was expecting the same results, but all it offers me are matches in subdirectories. When there are files in the working directory that should match, it sends me: find: expression must come before paths: mytest.c

What does this issue signify, and how can I find matches in the current directory and its subdirectories?

Asked by Chris Finley

Solution #1

You’re running into the shell’s wildcard expansion, so what you’re actually passing to locate will look like:

find . -name bobtest.c cattest.c snowtest.c

…which results in a syntax error. Instead, try this:

find . -name '*test.c'

The single quotes around your file expression will prevent your wildcards from being expanded by the shell (bash).

Answered by Chris J

Solution #2

What’s happening is that the shell is expanding “*test.c” into a list of files. Try escaping the asterisk as:

find . -name \*test.c

Answered by Jim Garrison

Solution #3

Put it in quotation marks:

find . -name '*test.c'

Answered by rkulla

Solution #4

From find manual:

NON-BUGS         

   Operator precedence surprises
   The command find . -name afile -o -name bfile -print will never print
   afile because this is actually equivalent to find . -name afile -o \(
   -name bfile -a -print \).  Remember that the precedence of -a is
   higher than that of -o and when there is no operator specified
   between tests, -a is assumed.

   “paths must precede expression” error message
   $ find . -name *.c -print
   find: paths must precede expression
   Usage: find [-H] [-L] [-P] [-Olevel] [-D ... [path...] [expression]

   This happens because *.c has been expanded by the shell resulting in
   find actually receiving a command line like this:
   find . -name frcode.c locate.c word_io.c -print
   That command is of course not going to work.  Instead of doing things
   this way, you should enclose the pattern in quotes or escape the
   wildcard:
   $ find . -name '*.c' -print
   $ find . -name \*.c -print

Answered by Nick Constantine

Solution #5

This question has previously been answered, as far as I can tell. All I want to do is share what has worked for me. A space was missed between (and -name. So, the proper method of selecting files while eliminating certain of them would be as follows:

find . -name 'my-file-*' -type f -not \( -name 'my-file-1.2.0.jar' -or -name 'my-file.jar' \) 

Answered by cell-in

Post is based on https://stackoverflow.com/questions/6495501/find-paths-must-precede-expression-how-do-i-specify-a-recursive-search-that