-exec 스크립트에서 COUNTER를 늘리는 방법은 무엇입니까?

-exec 스크립트에서 COUNTER를 늘리는 방법은 무엇입니까?

컨텍스트: zsh Catalina MacOS:

실행 가능한 스크립트베이츠 스탬프imagemagick을 사용하여 jpg 파일에 숫자를 태그합니다.

# BatesStamp: OVERWRITES and stamps ONE file with COUNTER  (upper left corner)
# usage  ./BatesStamp  COUNTER  PATH_FILE   
# to be used with find & -exec: https://unix.stackexchange.com/a/96239/182280   


COUNTER=$1     # 1st argument = number to be stamped upon .jpg file
PATH_FILE=$2   # 2nd argument = /path_to_file/Filename.jpg

convert $PATH_FILE  -auto-orient -gravity northWest  -font "Arial-Bold-Italic" -pointsize 175 \
   -fill red  -annotate +30+30   "$COUNTER"  $PATH_FILE;
   ((COUNTER++))  #https://stackoverflow.com/a/21035146/4953146
   echo "watermarked i= $COUNTER  $PATH_FILE"

목표는 디렉터리 트리의 모든 .jpg 파일에 고유 번호를 태그하는 것입니다. 나는 $COUNTER가 호출될 때마다 증가해야 한다고 생각합니다. 이렇게 하면 각 파일에 고유한 번호가 표시됩니다. 전략은 모든 하위 디렉터리를 반복하여 find.jpg 파일을 식별하고 각 .jpg 파일에 대해 $COUNTER++ BatesStamp를 사용하는 것입니다.

스크립트는 goBatesStamp.sh처리할 각 .jpg 파일을 실행하는 하위 디렉터리를 반복합니다.베이츠 스탬프

# goBastesStamp.sh
cd /Users/user/Desktop/AITH_USB_Hope_Submitted_MyCloud/PhotoGraphs_Work/A_Building_NoBulkhead. # navigate to top level directory
COUNTER=100   # initialize COUNTER
find /Users/user/Desktop/AITH_USB_Hope_Submitted_MyCloud/PhotoGraphs_Work/A_Building_NoBulkhead -iname "*.jpg" -exec ./BatesStamp $((COUNTER+=1)) {} \;  

문제는 find명령으로 시작하는 줄에 있습니다. 특히 COUNTER는 증가하지 않습니다.

테스트 결과 .jpg 파일에 숫자 100이 표시되어 있는 것으로 나타났습니다. $((COUNTER++)) 문제가 있는 것 같습니다. COUNTER를 증가시키고 증가된 COUNTER를 ./BatesStamp에 공급하는 올바른 구문은 무엇입니까?

답변1

내부에

find ... -exec ./BatesStamp $((COUNTER+=1)) {} ';'

$((COUNTER+=1))호출하기 전에 명령줄을 해석하는 셸에 의해 확장된 셸 코드 find이므로 find다음과 같이 호출됩니다.

find ... -exec ./BateStamp 101 {} ';'

찾은 모든 파일에 대해 ./BateStamp 101 path/to/the/file.

다음과 같이 변경하더라도:

export COUNTER=100
find ... -exec sh -c 'for f do ./BatesStamp "$((COUNTER+=1))"; done' sh {} +

for는 find자체 변수를 증가시키고 루프에서 여러 파일을 처리하는 쉘을 시작 하지만 with는 파일 배치에 대해 매번 여러 번 호출될 수 있고 위의 각 호출이 다시 발생하기 $COUNTER때문에 여전히 작동하지 않습니다. 100부터.find-exec cmd {} +cmdsh

여기에서 처리하려면 sh 또는 다른 쉘이나 프로그래밍 언어를 한 번 호출해야 합니다.모두한 번의 통화로 파일을 제출하세요.

이제 이미 사용하고 있으므로 zsh다음을 수행할 수 있습니다.

#! /bin/zsh -

top=/Users/user/Desktop/AITH_USB_Hope_Submitted_MyCloud/PhotoGraphs_Work/A_Building_NoBulkhead
n=100
for file in $top/**/*.jpg(NDn.); do
  mogrify -auto-orient \
          -gravity northWest \
          -font "Arial-Bold-Italic" \
          -pointsize 175 \
          -fill red \
          -annotate +30+30 $n \
          -- $file &&
    print -ru2 -- $file was watermarked with $n
  (( n++ ))
done

여기서 사용됨zsh 재귀 전역파일을 찾는 대신 ( **/레벨이 0 이상인 하위 디렉터리와 일치)findjpg. 글로벌 예선입력 목록을 n무작위 순서로 처리하는 대신 1씩 숫자로 정렬하고 대신 ImageMagick 명령을 find사용하여 이미지를 제자리에서 편집합니다.mogrifyconvert

sh스크립트를 직접 실행하지 않고 인터프리터로 해석하려면 시스템에 파일 내용을 해석하는 데 사용할 인터프리터를 알려주는 she-bang 줄( )이 필요 합니다 #! /path/to/the/interpreter. 또는 파일에서 인터프리터를 수동으로 호출할 수 있습니다. zsh /path/to/that/file또는 현재 사용 중인 대화형 쉘(zsh의 경우)이 source /path/to/that/file이를 직접 또는 서브쉘에서 해석하여 쉘 세션의 환경을 변경하지 않도록 할 수 있습니다 (source /path/to/that/file).


1 글로벌 한정자 n( numericglobsort전역적으로 활성화할 수도 있는 옵션)가 없으면 정렬은 어휘적이므로 image2.jpg예를 들어뒤쪽에 image10.jpg2정렬 순서대로 맨 마지막에 오기 때문입니다 .1

-² Shebang의 추가 내용을 알고 싶다면 #! /bin/zsh -다음을 참조하십시오.왜 "#!/bin/sh -" shebang에 "-"가 있나요?

관련 정보