如果找到的内容位于当前目录中,则尝试让“查找”执行条件深度搜索。找到的是一个文件,然后用语言解释它的输出,否则像平常一样输出
$ find ~+ -maxdepth 1 \( -type f -printf 'File: %p\n' -o -printf '%p\n' \) -o -mindepth 2 -printf '%p\n'
find: warning: you have specified the -mindepth option after a non-option argument (, but options are not positional (-mindepth affects tests specified before it as well as those specified after it)..
为什么失败以及如何解决这样的需求条件?
答案1
-maxdepth
/ -mindepth
(一个非标准的 GNU 扩展,尽管现在被很多其他find
实现支持)不是状况谓词,它们是影响下降到目录的方式的全局标志find
。
可以通过和 的-maxdepth
组合来实现标准的效果-path
-prune
。
FreeBSD 的find
必须-depth n/-n/+
匹配深度n
/ < n
/>的文件n
,因此在 FreeBSD 或衍生产品(macOS、DragonFly BSD ...)上,它只是:
find ~+ -depth 1 -type f -exec printf 'File: %s' {} ';' -o -print
这里使用-exec printf
代替 GNU 特定的-printf
.
从技术上讲,printf
可能会失败,从而触发-print
.使用-exec ... {} +
代替-exec ... {} ';'
可以解决这个问题,但会影响显示顺序。或者可以改为:
find ~+ -depth 1 -type f '(' -exec printf 'File: %s' {} ';' -o -true ')' -o -print
或者:
find ~+ '(' ! -depth 1 -o ! -type f ')' -print -o -exec printf 'File: %s' {} ';'
标准情况下,-path
可以使用它来代替(尽管不是那么简单)。
LC_ALL=C find ~+/. -path '*/./*/*' -print -o \
-type f -printf 'File: %p\n' -o -print
或者将深度限制为 2 (如我答案的早期版本,我认为你-mindepth 2
是-maxdepth 2
)
LC_ALL=C find ~+/. -path '*/./*/*' -prune -print -o \
-type f -printf 'File: %p\n' -o -print
(仍然不是标准,因为-printf
GNU 特定)。
我们附加/.
到路径(否则保证不会出现在$PWD
/中),以标记s~+
的深度 0 点。find
-path
你不能使用-path "$PWD/*/*"
代替(如您建议的编辑$PWD
),因为这对于包含通配符或反斜杠的值无法正常工作(因为-path
将其参数视为通配符模式)。
比较:
$ 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
另一种方法是追加//
,尽管这种方法的可移植性较差,因为某些find
实现会删除那些多余的尾随/
。
您可以通过管道来sed 's:/\./:/:'
删除/./
输出中的那些内容。
LC_ALL=C
GNU 需要它find
,无法*
匹配包含不形成有效字符的字节序列的路径组件。
虽然 GNUfind
没有谓词来显式匹配文件的深度,但它的-printf
谓词可以打印那个深度。所以在这里,你可以将该File:
前缀添加到深度为 1 的常规文件中,并进行一些后期处理:
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