-maxdepth
/-mindepth
(a non-standard GNU extension, though now supported by quite a few other find
implementations) are not condition predicates, they're global flags that affect the way find
descends into directories.
It's possible to implement the effect of -maxdepth
standardly with a combination of -path
and -prune
.
FreeBSD's find
has -depth n/-n/+
to match files at depth n
/ < n
/ > n
, so on FreeBSD or derivatives (macOS, DragonFly BSD...), it would just be:
find ~+ -depth 1 -type f -exec printf 'File: %s' {} ';' -o -print
here using -exec printf
in place of the GNU-specific -printf
.
Technically, printf
could fail which would trigger -print
. Using -exec ... {} +
instead of -exec ... {} ';'
would address that but affect the order of display. Or it could be changed to:
find ~+ -depth 1 -type f '(' -exec printf 'File: %s' {} ';' -o -true ')' -o -print
Or:
find ~+ '(' ! -depth 1 -o ! -type f ')' -print -o -exec printf 'File: %s' {} ';'
Standardly, -path
can be used instead (though not as straightforwardly).
LC_ALL=C find ~+/. -path '*/./*/*' -print -o \
-type f -printf 'File: %p\n' -o -print
Or to limit the depth to 2 (as in an earlier version of my answer where I thought your -mindepth 2
was -maxdepth 2
)
LC_ALL=C find ~+/. -path '*/./*/*' -prune -print -o \
-type f -printf 'File: %p\n' -o -print
(still not standard as -printf
is GNU specific).
We append /.
to the path (which is otherwise guaranteed not to occur in $PWD
/~+
), to mark the depth 0 point for find
's -path
.
You can't use -path "$PWD/*/*"
instead (as in your suggested edit) as that wouldn't work properly for values of $PWD
that contain wildcard characters or backslashes (since -path
considers its argument as a wildcard pattern).
Compare:
$ mkdir -p '[1]/2/3/4'
$ touch '[1]/2/3/4/file'
$ cd '[1]'
$ LC_ALL=C find ~+ -path "$PWD/*/*" -print -o -type f -printf 'File: %p\n' -o -print
/tmp/[1]
/tmp/[1]/2
/tmp/[1]/2/3
/tmp/[1]/2/3/4
File: /tmp/[1]/2/3/4/file
$ LC_ALL=C find ~+/. -path '*/./*/*' -print -o -type f -printf 'File: %p\n' -o -print
/tmp/[1]/.
/tmp/[1]/./2
/tmp/[1]/./2/3
/tmp/[1]/./2/3/4
/tmp/[1]/./2/3/4/file
Another approach is to append //
, though that's less portable as some find
implementations remove those excess trailing /
s.
You can pipe to sed 's:/\./:/:'
to remove those /./
s on output.
LC_ALL=C
is needed with GNU find
where *
fails to match path components that contain sequence of bytes not forming valid characters.
While GNU find
has no predicate to explicitly match on the depth of files, its -printf
predicate can print that depth. So here, you could add that File:
prefix to regular files at depth 1 with some post-processing:
find . -printf '%d%y,%p\0' | # print depth, type and path
sed -z 's/^1f,/&File: /' | # add "File: " prefix for regulars at depth 1
cut -zd, -f2- | # remove the depth and type
tr '\0' '\n' # NL delimited for user consumption
-path
is taken as a pattern, so-path "$PWD/*/*"
wouldn't work with arbitrary values of$PWD
(those containing wildcards or backslashes specifically). – Stéphane Chazelas Oct 03 '20 at 09:28-mindepth 2
and not-maxdepth 2
though, so I'll need to change that. – Stéphane Chazelas Oct 03 '20 at 09:31-path "$PWD/*/*"
wouldn't work with arbitrary values of$PWD
. See comment above and my latest edit that should also fix my earlier misreading of your question. – Stéphane Chazelas Oct 03 '20 at 09:41-depth
is a POSIX standardfind
primary that inverts the order of the output. It causes the directory content to be printed before the directory. This is not related to-mindepth
at all. Also note thatlibfind
implements-mindepth
and-maxdelth
as normal primaries that always yield in TRUE. – schily Oct 03 '20 at 22:41-depth
alone standard predicate here, but of the unrelated FreeBSDfind
's-depth n
extension. The behaviour forfind . -depth 1
is unspecified by POSIX. By GNU extension, I meant it was of GNU origin.-mindepth
/-maxdepth
is now supported by a few other implementations. – Stéphane Chazelas Oct 04 '20 at 05:38-amin
primary ingfind
compared to the enhanced-atime
inlibfind
(see http://schilytools.sourceforge.net/man/man1/sfind.1.html) and FreeBSD, but the hard to parse-depth
extension from FreeBSD is an unhappy decision.gfind
s claim-mindepth
to be an option is nonsense, since then it would need to appear before file type arguments. BTW: Even FreeBSD supports-mindepth
, so it makes no sense to mention the FreeBSD mistake with-depth xxx
. – schily Oct 04 '20 at 11:26-mindepth
/-maxdepth
and-depth
don't do the same thing.-mindepth
/-maxdepth
are global flags (like you say not options in that they are not processed like the-L
,-H
... ones) which affect the traversal and would be of no use in this Q&A.-depth n
is a condition predicate that returns true if the file is at depth n but otherwise doesn't affectfind
's traversal of the directory tree (as long as you don't use-prune
based on its result). – Stéphane Chazelas Oct 04 '20 at 12:28find
initially didn't have any option in thegetopt()
sense of the term. GNU find classifies its predicates as Options, Test or Action ones and has done so since long before POSIX introducedgetopt()
-style options for it (one of which,-L
, duplicates the-follow
option predicate). I used flag in my answer to avoid the possible confusion. – Stéphane Chazelas Oct 04 '20 at 13:13-depth n
matches at depth n. That's the predicate that answers exactly the OP's question. See edit where I make that more explicit. Without it, you have to use those convoluted approaches with-path
and where you need to fix the locale to C with all the implications it has. That's the whole point of my answer. – Stéphane Chazelas Oct 05 '20 at 14:16