zsh 不区分大小写的通配符

zsh 不区分大小写的通配符

上下文:macOS Catalina (zsh)

该脚本用于处理所有 JPEG 文件。此脚本不处理 .JPG 文件,但它确实处理 .jpg 文件。

top=/Users/user/Desktop/
for file in $top/**/*.jp*g(NDn.); do      #selects filetypes: .jpg .jpeg 
  mogrify -auto-orient \
          -gravity northWest \
          -font "Arial-Bold-Italic" \
          -pointsize 175 \
          -fill red \
          -annotate +30+30 $n \
          -- $file &&
  echo  $file "was watermarked with" $n | tee -a forLooplog.txt
  (( n++ ))
done

如何将第二行修改为不区分大小写并捕获 .JPG .JPEG 文件?

答案1

特别是对于你的情况,glob 是$top/**/*.jpg,我会不是全局关闭该caseglob选项(与打开nocaseglob打开相同),因为这会影响全局模式中的所有路径组件:

$ top=a zsh +o caseglob -c 'print -rC1 --  $top/*.jpg'
a/foo.jpg
a/foo.JPG
a/FOO.jpg
a/FOO.JPG
A/foo.jpg
A/foo.JPG
A/FOO.jpg
A/FOO.JPG

看看它如何找到( )中的所有jpg和文件,以及无关目录 ( ) 中的文件,这些文件恰好具有相同的名称但大写。即使您没有这样的目录,zsh 仍然会查找它们,这意味着它需要列出每个目录的内容,这些目录构成了使 glob 扩展成本更高的组件。JPG$topaA$top

IMO,nocaseglob最好忘记这个选项。它被添加到 zsh 中只是为了与bash² 兼容,并且添加它很可能是为了让 Cygwin / macos 等具有不区分大小写的文件系统 API 的系统的用户的生活更轻松。

相反,我使用了(#i)glob 运算符(with extendedglob),您可以在其中指定 glob 的哪一部分应不区分大小写(类似于~(i)ksh93 的):

set -o extendedglob # needed for (#i)
for file in $top/**/*.(#i)jp(e|)g(NDn.); do

或者你也可以这样做:

for file in $top/**/*.[jJ][pP]([eE]|)[gG](NDn.); do

就像在sh任何没有不区分大小写的全局运算符的 shell 中一样。

另请注意,*.jp(|e)g相反,*.jp*g它会匹配文件名,例如。my.jpeg.import.log


¹ 或CASEGLOBCASE_GLOBC_A_se_G_lob、 大小写和下划线在选项名称中被忽略,关闭选项的支持no是尝试使用 POSIX sh 选项(以及其他 shell' 包括 zsh 本身)来适应混乱,其中某些选项以no前缀,有些没有,没有明显的原因。

² 虽然 bash 行为不同(在我看来,至少在区分大小写文件名的系统上是更好的),但在这种情况下,a/*.jpg只会找到jpg/JPG文件a,而不是A因为它只对大小写不敏感的匹配路径组件确实有 glob 运算符([a]/*.jpg也会在 中找到jpg/文件)。JPGA

相关内容