有没有办法让 find 使用 shell 的 extglob shell 选项?

有没有办法让 find 使用 shell 的 extglob shell 选项?

简而言之,我本能地写了一个这样的命令来查找这两个文件prefix.extprefix_suffix.ext沿着层次结构向下查找

find /some/path -type f -name 'prefix?(_suffix).zip'

但它不起作用。

由于man find, under-name patter将模式称为“shell 模式”,因此我想知道是否可以控制应使用哪种模式,特别是是否extglob可以使用选项。

答案1

find只使用“基本”贝壳图案,如 POSIX 中所述。它不支持extglob-style glob(尽管 GNU 实现说它使用fnmatch, 和GNU C 库的实现fnmatch支持扩展模式)。

如果您使用的是 GNU find,则可以使用正则表达式进行过滤;看文档的相关部分详情:

-regex '.*/prefix\(_suffix\)?\.zip'

使用默认的正则表达式类型,或者

-regextype posix-extended -regex '.*/prefix(_suffix)?\.zip'

与 ERE。

答案2

正如其他人已经指出的那样,该find实用程序默认不支持 shellbash和其他(最初从kshshell 继承)中发现的扩展通配模式。

您可以使用shellbash来执行这些测试:

find /some/path -type f \
    -exec bash -O extglob -c '[[ ${1##*/} == prefix?(_suffix).zip ]]' bash {} \; \
    -print

但这是非常低效的,因为您需要bash为您想要调查的每个文件生成一个进程。使用一种或多种正常模式重写扩展通配模式会更有意义:

find /some/path -type f \
    \( -name prefix.zip -o -name prefix_suffix.zip \) \
    -print

这样做的好处是便携且易于理解。

答案3

另一个答案提到了正则表达式,这让我想到了一个明显的解决方案:使用-regex而不是-name

find /some/path -type f -regex '.*/prefix\(_suffix\)?\.zip'

我怀疑它可能会慢一些,但也许不会慢那么多。

相关内容