首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“查找”不能执行条件深度搜索

“查找”不能执行条件深度搜索
EN

Unix & Linux用户
提问于 2020-10-03 07:34:30
回答 1查看 213关注 0票数 1

尝试让“查找”执行条件深度搜索,如果发现是当前的dir。找到的是一个文件,然后用口头解释它的输出,否则就像正常的输出一样。

代码语言:javascript
复制
$ 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)..

为什么失败了,如何解决这样的条件呢?

EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2020-10-03 08:00:17

-maxdepth/-mindepth (一个非标准的GNU扩展,尽管现在得到了许多其他find实现的支持)不是条件谓词,它们是影响find进入目录的方式的全局标志。

实现以下效果是可能的-maxdepth标准地结合了-path-prune

FreeBSDfind-depth n/-n/+来匹配深度为n /< n /> n的文件,例如FreeBSD或衍生产品(macOS,DragonFly BSD.),它只是:

代码语言:javascript
复制
find ~+ -depth 1 -type f -exec printf 'File: %s' {} ';' -o -print

这里使用-exec printf代替特定于GNU的-printf

从技术上讲,printf可能会失败,从而触发-print。使用-exec ... {} +而不是-exec ... {} ';'可以解决这个问题,但会影响显示的顺序。也可以改为:

代码语言:javascript
复制
find ~+ -depth 1 -type f '(' -exec printf 'File: %s' {} ';' -o -true ')' -o -print

或者:

代码语言:javascript
复制
find ~+ '(' ! -depth 1 -o ! -type f ')' -print -o -exec printf 'File: %s' {} ';'

标准地说,可以使用-path (虽然不是直接使用)。

代码语言:javascript
复制
LC_ALL=C find ~+/. -path '*/./*/*' -print -o \
  -type f -printf 'File: %p\n' -o -print

或者将深度限制在2(在我的答案的早期版本中,我认为您的-mindepth 2-maxdepth 2)

代码语言:javascript
复制
LC_ALL=C find ~+/. -path '*/./*/*' -prune -print -o \
  -type f -printf 'File: %p\n' -o -print

(仍然不标准,因为-printf是特定于GNU的)。

我们将/.附加到路径(否则保证不会发生在$PWD/~+中),以标记find's -path的深度0点。

您不能使用-path "$PWD/*/*" (在你建议的编辑中),因为对于包含通配符或反斜杠的$PWD值(因为-path认为它的参数是通配符模式),它不能正常工作。

比较:

代码语言:javascript
复制
$ 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实现消除了那些落后于/s的过多功能。

您可以转到sed 's:/\./:/:'以删除输出上的/./s。

在GNU find中需要D41,其中*无法匹配包含未形成有效字符的字节序列的路径组件。

虽然GNU find没有可以显式匹配文件深度的谓词,但它的-printf谓词可以打印该深度。因此,您可以在深度为1的常规文件中添加File:前缀,并进行一些后处理:

代码语言:javascript
复制
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
票数 2
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/612688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档