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는 계속해서 해당 디렉토리를 찾습니다. 즉, 글로벌 확장 비용을 더 비싸게 만드는 구성 요소를 형성하는 각 디렉토리의 내용을 나열해야 함을 의미합니다.JPG$topaA$top

IMO, nocaseglob이 옵션은 잊어버리는 것이 좋습니다. 이는 단순히 ²와의 호환성을 위해 zsh에 추가되었으며 bash, 대소문자를 구분하지 않는 파일 시스템 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대소문자를 구분하지 않는 전역 연산자가 없는 다른 쉘 과 같습니다 .

또한 *.jp(|e)g대신 *.jp*g파일 이름과 일치합니다.my.jpeg.import.log


¹ 또는 CASEGLOB, CASE_GLOB, C_A_se_G_lob, 대소문자 및 밑줄은 옵션 이름에서 무시됩니다. 옵션 지원을 끄는 것은 noPOSIX sh 옵션(및 zsh 자체를 포함한 다른 쉘)을 사용하여 혼란을 수용하려는 시도입니다. 이 중 일부는 no접두사가 붙고 일부는 접두사가 붙지 않으며 없음 명백한 이유.

² bash는 다르게 동작하지만(제 생각에는 적어도 파일 이름에서 대소문자를 구분하는 시스템에서는 더 좋습니다), 이 경우 / 파일 만 a/*.jpg발견됩니다 . 대소문자를 구분하지 않기 때문 이 아닙니다.jpgJPGaA경로 구성 요소실제로 glob 연산자가 있습니다( /file [a]/*.jpg에도 있음 jpg).JPGA

관련 정보