Chris Finley
Chris Finley

Reputation: 4051

"find: paths must precede expression:" How do I specify a recursive search that also finds files in the current directory?

I am having a hard time getting find to look for matches in the current directory as well as its subdirectories.

When I run find *test.c it only gives me the matches in the current directory. (does not look in subdirectories)

If I try find . -name *test.c I would expect the same results, but instead it gives me only matches that are in a subdirectory. When there are files that should match in the working directory, it gives me: find: paths must precede expression: mytest.c

What does this error mean, and how can I get the matches from both the current directory and its subdirectories?

Upvotes: 308

Views: 369745

Answers (10)

Er Rdh Tiwari
Er Rdh Tiwari

Reputation: 1

The issue is with how the command substitution and piping are being handled in the script. You can simplify the command without using command substitution for find. Here is the corrected script:

find ./test/ -maxdepth 1 -type f -print0 | xargs -0 mv -t ./test/new

If you need to use the variable fbc, you should use eval to properly execute the command:

fbc="find ./test/ -maxdepth 1 -type f -print0 | xargs -0 mv -t ./test/new"
eval ${fbc}

This should fix the error you're encountering.

Upvotes: 0

cell-in
cell-in

Reputation: 789

I see this question is already answered. I just want to share what worked for me. I was missing a space between ( and -name. So, the correct way of chosen files with excluding some of them would be like below;

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

Upvotes: 10

Jerinaw
Jerinaw

Reputation: 5529

I got this error when I forgot the space between the ( and -name.

find . -not \(-name 'scripts' \)

Should have been

find . -not \( -name 'scripts' \)

Upvotes: 0

Jose Sakuda
Jose Sakuda

Reputation: 1

You can try this:

cat $(file $( find . -readable) | grep ASCII | tr ":" " " | awk '{print $1}')

with that, you can find all readable files with ascii and read them with cat

if you want to specify his weight and no-executable:

cat $(file $( find . -readable ! -executable -size 1033c) | grep ASCII | tr ":" " " | awk '{print $1}')

Upvotes: 0

Nick Constantine
Nick Constantine

Reputation: 1091

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

Upvotes: 26

HappyTown
HappyTown

Reputation: 6514

I came across this question when I was trying to find multiple filenames that I could not combine into a regular expression as described in @Chris J's answer, here is what worked for me

find . -name one.pdf -o -name two.txt -o -name anotherone.jpg

-o or -or is logical OR. See Finding Files on Gnu.org for more information.

I was running this on CygWin.

Upvotes: 2

Vikash Singh
Vikash Singh

Reputation: 910

In my case i was missing trailing / in path.

find /var/opt/gitlab/backups/ -name *.tar

Upvotes: -1

Jim Garrison
Jim Garrison

Reputation: 86774

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

Upvotes: 35

Callie J
Callie J

Reputation: 31296

Try putting it in quotes -- you're running into the shell's wildcard expansion, so what you're acually passing to find will look like:

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

...causing the syntax error. So try this instead:

find . -name '*test.c'

Note the single quotes around your file expression -- these will stop the shell (bash) expanding your wildcards.

Upvotes: 503

rkulla
rkulla

Reputation: 2524

Try putting it in quotes:

find . -name '*test.c'

Upvotes: 23

Related Questions