find
's algorithm is as follows:
- For each path given on the command line, let the current entry be that path, then:
- Match the current entry against the expression.
- If the current entry is a directory, then perform steps 1 and 2 for every entry in that directory, in an unspecified order.
With the -depth
primary, steps 1 and 2 are executed in the opposite order.
What you're asking find
to do is to consider files before directories in step 2. But find
has no option to do that.
In your example, all names of matching files come before names of subdirectories in the same directory, so find . -iname '.note' | sort
would work. But that obviously doesn't generalize well.
One way to process non-directories before directories is to run a find
command to iterate over directories, and a separate command (possibly find
again) to print matching files in that directory.
find -type d -exec print-matching-files-in {} \;
If you want to use a find
expression to match files, here's a general structure for the second find
command to iterate only over non-directories in the specified directory, non-recursively (GNU find required):
find -type d -exec find {} -maxdepth 1 \! -type d … \;
For example:
find -type d -exec find {} -maxdepth 1 \! -type d -iname '.note' \;
In zsh, you can write
print -l **/(#i).note(Od)
**/
recurses into subdirectories; (#i)
(a globbing flag) interprets what follows as a case-insensitive pattern, and (Od)
(a glob qualifier) orders the outcome of recursive traversals so that files in a directory are considered before subdirectories. With (Odon)
, the output is sorted lexicographically within the constraint laid out by Od
(i.e. the primary sort criterion comes first).