-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または他のシェルまたはプログラミング言語を一度呼び出す必要があります。みんな1回の通話でファイルを送信してください。

これですでに使用しているので、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グローバル修飾子nnumericglobsortグローバルに有効にすることもできるオプション)がない場合、ソートは語彙であるため、image2.jpgたとえば後ろに image10.jpg2ソート順に最後に来るからです。1

-² シェバンの詳細を知りたい場合は、#! /bin/zsh -以下を参照してください。なぜ"#!/bin/sh -" shebangに "-"があるのですか?

関連情報