0

I am always running into this problem without learning.

When searching for a file with the starting point in another directory I give the full path to the starting point and it does not work. Same happens when I am in the starting directory and give the full path to the starting point.

find /path/from/start/. -path './anaconda3/*' -prune -o -name '*R' -print

goes straight to the "pruned" directory like there was candy in it.

If I'm at the starting point, starting from . works fine. Otherwise find does not prune the path I'm trying to escape.

find . -path './anaconda3/*' -prune -o -name '*R' -print

works.

Maybe a detailed answer will settle this problem, sometimes I learn but the next time I face the find command I run into the same problem like I have never done this before. The -path pattern chapter of the man page is trying to say something but I think it is in vogon and I do not possess a babel fish.

5

-path matches against the full pathname generated by find. When you start from ., the pathname starts with that; when you start from /path/from/start (the /. isn’t necessary and will only complicate matters), the pathname starts with /path/from/start.

So you need to match against the full path.

find /path/from/start -path '/path/from/start/anaconda3/*' -prune -o -name '*R' -print

Since this will prune /path/from/start/anaconda3 itself, you don’t even need the /* part at the end:

find /path/from/start -path /path/from/start/anaconda3 -prune -o -name '*R' -print

Basically, with -path you need to remember that the start path is repeated in the “criteria” paths:

find /path/from/start -path /path/from/start/anaconda3 -prune -o -name '*R' -print
     ^^^^^^^^^^^^^^^^       ^^^^^^^^^^^^^^^^

find . -path './anaconda3/*' -prune -o -name '*R' -print
     ^        ^

If that’s the only anaconda3 directory you want to prune, or if you want to prune all anaconda3 directories, you can use -name instead:

find /path/from/start -name anaconda3 -prune -o -name '*R' -print

All this also applies when you specify multiple start paths: each -path expression will match against the full pathname produced from any of the start paths. So you could have the following:

find /path/from/start /otherpath/from/elsewhere \
     -path /path/from/start/anaconda3 -prune -o \
     -path /otherpath/from/elsewhere/anaconda3 -prune -o \
     -name '*R' -print
4
  • Also you could have multiple starting points... find ./foo ./bar -path ./foo/test would not match ./bar/test. The -printf action of GNU find has the format directives %H and %P for the starting point corresponding to the file and the path under the starting point. But I don't think there's a similar condition to go between -path and -name.
    – ilkkachu
    Sep 17 at 10:58
  • 1
    Indeed, it’s worth describing multiple start path handling; I’ve added that. I considered mentioning %H and %P but thought that would just end up confusing since they can’t be used to match :-/. Sep 17 at 11:05
  • Removing .s and including full path to path did the trick. I thought flaunting dots was good practice in linux, that is what the "cool linux kids" do.
    – AWE
    Sep 17 at 12:24
  • @AWE flaunting dots can be useful in some circumstances, e.g. with mv to avoid moving multiple files to a single file instead of a directory; but with find it’s not. Sep 17 at 12:27

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.