The -depth
primary to find
causes it to perform a depth-first search.
However, the default sequence is not a breadth-first search.
The default sequence could be informally described as a "depth-first traversal that handles nodes when they are first encountered rather than doing so during backtracking."
I have an actual need for breadth first search. How can I make find
behave in this way?
For illustration, with the following setup:
$ mkdir -p alpha/{bravo,charlie,delta}
$ touch alpha/charlie/{alpha,beta,gamma,phi}
find
has the following default behavior:
$ find alpha
alpha
alpha/charlie
alpha/charlie/alpha
alpha/charlie/phi
alpha/charlie/beta
alpha/charlie/gamma
alpha/delta
alpha/bravo
and with -depth
, it performs as follows:
$ find alpha -depth
alpha/charlie/alpha
alpha/charlie/phi
alpha/charlie/beta
alpha/charlie/gamma
alpha/charlie
alpha/delta
alpha/bravo
alpha
However, what I want is the following (fictitious) option:
$ find alpha -bfs
alpha
alpha/charlie
alpha/delta
alpha/bravo
alpha/charlie/alpha
alpha/charlie/phi
alpha/charlie/beta
alpha/charlie/gamma
In other words I need find
to process/report on all files/dirs at a given depth before proceeding further.
How can I do this?
Best Answer
You can do it with just shell wildcards. Build up a pattern with progressively more directory levels.
This misses dot files. Use
FIGNORE='.?(.)'
in ksh,shopt -s dotglob
in bash, orsetopt glob_dots
in zsh to include them.Caveats:
If you want to choose the order or directories and non-directories, and performance isn't critical, you can make two passes and test
[ -d "$file" ]
on each pass.