如何在-exec脚本中增加COUNTER?

gat*_*ack 4 find shell-script exec

上下文:zsh Catalina MacOS:

可执行脚本BatesStamp使用 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++))  #/sf/answers/1472460251/
   echo "watermarked i= $COUNTER  $PATH_FILE"
Run Code Online (Sandbox Code Playgroud)

目标是用唯一的编号标记目录树中的所有 .jpg 文件。我相信每次调用 $COUNTER 时都必须递增:这确保每个文件都标有唯一的编号。该策略是遍历所有子目录以find识别 .jpg 文件,并使用 $COUNTER++ BatesStamp 每个 .jpg 文件。

该脚本goBatesStamp.sh遍历子目录来执行要由BatesStamp处理的每个 .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)) {} \;  
Run Code Online (Sandbox Code Playgroud)

问题出在以find命令开头的行中。具体来说,COUNTER 不会递增。

测试显示 .jpg 文件标有数字 100 看来 $((COUNTER++)) 是问题所在。将 COUNTER 加一并将递增的 COUNTER 送入 ./BatesStamp 的正确语法是什么?

Sté*_*las 7

在里面

\n
find ... -exec ./BatesStamp $((COUNTER+=1)) {} \';\'\n
Run Code Online (Sandbox Code Playgroud)\n

shell 代码,$((COUNTER+=1))由在调用命令之前解释该命令行的 shell 扩展find,因此find调用方式为:

\n
find ... -exec ./BateStamp 101 {} \';\'\n
Run Code Online (Sandbox Code Playgroud)\n

对于它找到的每个文件,它都会调用./BateStamp 101 path/to/the/file.

\n

即使你把它改成:

\n
export COUNTER=100\nfind ... -exec sh -c \'for f do ./BatesStamp "$((COUNTER+=1))"; done\' sh {} +\n
Run Code Online (Sandbox Code Playgroud)\n

forfind来启动一个 shell,它会增加自己的$COUNTER变量并在循环中处理多个文件,但这仍然不起作用,因为findwith-exec cmd {} +仍可能调用cmd多次,每次调用一批文件,并且sh上述每次调用都会再次从 100 开始。

\n

在这里,您需要一次调用 sh 或某种其他 shell 或编程语言,以便在一次调用中处理所有文件。

\n

既然您已经在使用zsh,您应该能够执行以下操作:

\n
find ... -exec ./BatesStamp $((COUNTER+=1)) {} \';\'\n
Run Code Online (Sandbox Code Playgroud)\n

这里使用zsh 递归 glob**/匹配 0 个或更多级别的子目录)而不是find查找jpg文件(仅限于带有. glob 限定符的常规文件,并使用 \xc2\xb9 对输入列表进行数字排序n,而不是像那样以随机顺序处理它们find)并使用mogrify而不是convertImageMagick 命令来就地编辑图像

\n

请注意,对于要由解释器解释而不是sh直接执行的脚本,您需要一个 she-bang 行 ( #! /path/to/the/interpreter) 来告诉系统使用哪个解释器来解释文件的内容。或者您可以在 file: 上手动调用解释器zsh /path/to/that/file,或者让您当前使用的交互式 shell(如果是 zsh)直接使用子 shellsource /path/to/that/file或在子 shell 中解释它,这样它就不会改变 shell 会话的环境(source /path/to/that/file)

\n
\n

\xc2\xb9 没有nnumericglobsort也可以全局启用的选项)glob 限定符,排序是词法的,因此image2.jpg例如将出现在后面 image10.jpg,因为按排序规则2出现在后面1

\n

-\xc2\xb2 如果您想知道 shebang中的额外内容#! /bin/zsh -,请参阅为什么“#! /bin/sh -” shebang 中的“-”?

\n