Zsh

zsh 不區分大小寫的萬用字元

  • November 22, 2021

上下文: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 文件?

特別是對於 glob 為 的情況$top/**/*.jpg,我不會全域關閉該caseglob選項(與打開nocaseglob¹相同),因為這會影響 glob 模式中的所有路徑組件:

$ 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``$top``a``A``$top

IMO,nocaseglob最好忘記該選項。它只是為了與bash² 兼容而添加到 zsh 中,並且很可能是為了讓具有不區分大小寫的文件系統 API 的系統(如 Cygwin / macos)的使用者的生活更輕鬆。

相反,我使用了(#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*gwhich 將匹配文件名,例如。my.**jp**eg.import.lo**g**


¹ 或CASEGLOB, CASE_GLOB, C_A_se_G_lob, 大小寫和下劃線在選項名稱中被忽略,no關閉選項的支持是嘗試適應 POSIX sh 選項(以及其他 shell,包括 zsh 本身)的混亂,其中某些選項以 a 命名no前綴和一些沒有立即明顯的原因。

² 儘管在這種情況下 bash 行為不同(並且更可取的 IMO,至少在具有區分大小寫文件名的系統上),但它只會在 中a/*.jpg找到jpg/JPG文件a,而不是因為它只對具有 glob 運算符的路徑組件A進行不區分大小寫的匹配(也會在 中找到/文件)。[a]/*.jpg``jpg``JPG``A

引用自:https://unix.stackexchange.com/questions/678439