13

As I understand it the -depth option of the find command causes the specified actions to take place on the way out of a directory (and maybe I understand it wrong) during a depth-first traversal of a tree structure.

Without the -depth option specified, does it normally make an action occur before the depth-first traversal is complete, or does it do a breadth-first traversal of the directories and run the action first normally?

leeand00
  • 4,443
  • 10
  • 51
  • 78

1 Answers1

19

find uses a depth-first strategy (as opposed to breadth-first), whether -depth is specified or not. -depth only guarantees that sub-directories are processed before their parents.

A quick example:

mkdir -p a/{1,2,3} b c
find .

produces

.
./a
./a/2
./a/1
./a/3
./b
./c

whereas

find . -depth

produces

./a/2
./a/1
./a/3
./a
./b
./c
.

If you want breadth-first search, you can use bfs which is a breadth-first implementation of find.

Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
  • Also I just noticed that using -depth clobbers the use of e.g. -name .git -prune to skip processing of the git folder... I wonder if there is another way to tell find to exclude some subfolders, which works despite -depth ? – Razzle Jun 02 '21 at 07:28
  • @Razzle `-prune` *can’t* work with `-depth` because the latter causes subdirectories to be processed first — so by the time `-prune` comes into play, the subdirectories and files which would be pruned have already been processed. The alternatives depend on your exact use-case, for example `find . -depth \( -path './.git*' -prune \) -o -print` skips `.git` and its contents. Perhaps you could [ask a new question](https://unix.stackexchange.com/questions/ask) with the details of what you’re trying to do. – Stephen Kitt Jun 02 '21 at 07:53
  • Seems to me you just showed me a way to use -depth while omitting .git and its subfolders - Bravo! (If it works when I test it :D ). But didn't you also just contradict yourself by demonstrating that prune _can_ work with depth? (You just need to add the pruning clause in the brackets?) -Thanks! – Razzle Jun 03 '21 at 10:54
  • You lose the major feature of `-prune` which is to reduce the amount of processing required. The command above is effectively equivalent to `find . -depth ! -path './.git*'`. – Stephen Kitt Jun 03 '21 at 11:07
  • Sadly `find . -depth \( -path './.git*' -prune \) -o -print` did not skip .git and its contents, when I just now tried it. HOWEVER the suggested equivalent command (tweaked a bit here: only dirs) `find . -depth ! -path './.git*' -type d` DID give me the folder tree (depth first listing) while excluding the .git contents. BRAVO and thanks! I have never really got to grips with negations in find paths. Must give them a closer look... – Razzle Jun 03 '21 at 15:31
  • @Razzle that’s odd, it works for me... You mean that `find . -depth \( -path './.git*' -prune \) -o -print | grep ./.git` produces output? – Stephen Kitt Jun 03 '21 at 15:34
  • Yes, huge number of files under .git/hooks and .git/logs etc. comes out from the pruning version (Im using MinGW ie a git bash shell to test this out btw) – Razzle Jun 03 '21 at 15:36
  • OK, I’m not sure why it would fail on MinGW, but I don’t have a Windows environment to figure it out. – Stephen Kitt Jun 03 '21 at 15:42
  • Is the man page for GNU `find` wrong/misleading? "The `-depth` option for example makes `find` traverse the file system in a depth-first order." – Karel Vlk Aug 23 '23 at 10:09
  • @KarelVlk yes, it is misleading... – Stephen Kitt Aug 23 '23 at 11:25