按名称查找文件全局模​​式或正则表达式,但允许在开头精确匹配,在结尾仅允许某些字符

按名称查找文件全局模​​式或正则表达式,但允许在开头精确匹配,在结尾仅允许某些字符

我正在尝试匹配一些共享基本名称但末尾附加了大小信息的图像文件来find . -name 'Name*'匹配文件,例如:

Name.jpg
[email protected]
Name-180x101.jpg
[email protected]

然而我的全局模式也匹配:

NameLonger.jpg
[email protected]
NameLonger-180x101.jpg
[email protected]

第二组是不受欢迎的。

如何调整我的find命令以命中第一组但忽略第二组?是否可以使用全局模式,或者是否需要正则表达式?

注意:对于这种情况,尺寸信息 (-180x101) 始终为“-”,然后是任意数量的数字,然后是“x”,然后是任意数量的数字。如果文件包含“@​​2x”,则它始终位于末尾。

注意:它还必须命中纯文件,例如:Name.jpg.

提前致谢。

答案1

使用zsh,具体说明您想要的文件名格式:

print -rC1 -- **/Name(-<->x<->|)(@<->x|).jpg(DN)
  • print -rC1print r哦,关于1 C专栏
  • **/: 递归通配符
  • (a|b): 交替,就像(x|)ERE一样(x)?
  • <x-y>:表示整数 x 到 y 的十进制数字序列,<->表示任意数字的数字序列。
  • D: dotglob: 也可以像这样查看隐藏目录find
  • N: nullglob: 如果没有匹配项,请不要抱怨,而是扩展为空。

GNUfind等效项(没有文件排序,并且./每个路径都有前缀):

LC_ALL=C find . -regextype posix-extended -regex \
  '.*/Name(-[0-9]+x[0-9]+)?(@[0-9]+x)?\.jpg'

(对于 BSD find,使用find -E .代替find . -regextype posix-extended

有了标准find,也许:

find . -name '.*/Name[-@.]*'

如果您需要的只是排除就足够了NameLonger

简单的通配符模式没有+,?|运算符的等效项。可以用多个-nameand! -name与 AND 和 ORed 一起做一些等效的事情(例如接受Name-*x*.jpg 但拒绝、、、Name-*[!0-9]*x*[!0-9]*.jpg等),但这将非常麻烦,因为您需要数百个这样的操作来处理所有情况。Name-x*Name-*x.jpg

该函数的 GNU libc 实现fnmatch()(由 所使用find -name)可以被告知支持一些 ksh88 扩展 glob 运算符(FNM_EXTMATCH标志),这些运算符带来了正则表达式等价性(+(...), ... 也由或 所?(...)支持),但据我所知,甚至连 GNU 实现都没有可以被告知使用它们。zsh -o kshglobbash -O extglobfind

POSIXly,您可以采用以下方法来awk优化匹配:

LC_ALL=C find . -name 'Name*' -exec awk '
  BEGIN {
    for (i = 1; i < ARGC; i++)
      if (ARGV[i] ~ "/Name(-[0-9]+x[0-9]+)?(@[0-9]+x)?\\.jpg$")
        print ARGV[i]
  }' {} +

(请记住,如果某些文件的路径太长而无法放入命令行,则可能会失败。并非所有find实现都能够找到路径比PATH_MAX无论如何都长的文件)。

相关内容