Search code examples
bashshellfindcygwinimagemagick

Generate uuids for files while using the find command in bash


I am having a bit of an issue. I am searching for some jpg files and using imagemagick to batch-watermark them.

I am running the following command in a cygwin bash shell:

find -iname '*.jpg' -execdir convert '{}' -resize 600x600 -fill white \
-undercolor '#00000080' -gravity SouthWest -annotate +0+5 \
$(uuidgen -r | grep -o "\w\{12\}" | tr '[:lower:]' '[:upper:]') {}-id.jpg \; \
-print

The problem I am having is that it seems like the line:

$(uuidgen -r | grep -o "\w\{12\}" | tr '[:lower:]' '[:upper:]')

is being run only once by the find command which in turn makes it that all files have exactly the same watermark text which is not my intention.

I also wanted to name all the files after the same watermark text like this by replacing this:

$(uuidgen -r | grep -o "\w\{12\}" | tr '[:lower:]' '[:upper:]') {}-id.jpg

with this:

wid=$(uuidgen -r | grep -o "\w\{12\}" | tr '[:lower:]' '[:upper:]') $wid.jpg

obviously what happens is that if there are 5 files in a folder, 1 would be created and overwritten 5 times, because the uuid is only created once...

What might be the reason why this happens? Any way for me to fix this?


Solution

  • The entire find command is scanned for expansion by the shell before it's executed, and, as you've said, the command expansion is done only once. The easiest thing to do is to make the the entire -execdir parameter a shell file and execute it from the find command with the shell.

    So make a file in your home directory called, say, watermark.sh, like this:

    wid=$(uuidgen -r | grep -o "\w\{12\}" | tr '[:lower:]' '[:upper:]')
    convert "$1" \
      -resize 600x600 \
      -fill white \
      -undercolor '#00000080' \
      -gravity SouthWest \
      -annotate +0+5 $wid \
      $wid.jpg
    

    And write your find command like this:

    find -iname '*.jpg' -execdir sh ~/watermark.sh '{}' \;