1

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.

1 Answer 1

7

-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, 2021 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, 2021 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, 2021 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, 2021 at 12:27

You must log in to answer this question.

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