does not run through and rename images...
#!/bin/zsh
# associate array for SHA key and duplicate filenames
typeset -gA dx=()
typeset -ga exifdata=()
typeset -giZ2 dupecnt=0
typeset -giZ3 nseq=1
typeset -g RPT="$HOME/Desktop/dupe_rpt.txt"
function rpt_writer () {
# print by SHA key, original file, and duplicates (in any child dir)
for k in ${(@k)dx};
do
print ${(k)dx[$k]} >> ${RPT}
print ${${(s:|:)dx[$k]}[1]} >> ${RPT}
printf '\t%s\n' ${${(s:|:)dx[$k]}[2,-1]} >> ${RPT}
printf '\n' >> ${RPT}
done
return
}
: <<'COMMENT'
Recursively processes child folders in specified parent directory. Extracts
image data using ExifTool, or where absent fabricate that data to provide a
standard TEMPLATE for file renaming. Encountered duplicates will add 2-digit
suffix to the TEMPLATE which forms the renaming OUTFMT string. Report writer
to audit duplicate images.
COMMENT
# parent folder passed into script on the command-line
STARTDIR="${1:a}"
# case-insensitive directive
setopt NOCASE_GLOB
for f in ${STARTDIR}/**/*.(raf|cr2|dng|jpg|jpeg|tif|tiff)(.N);
do
# ideally, place these three results into array if image supports them
exifdata=( $(/usr/local/bin/exiftool -s3 -d "%Y%m%d%H%M%S" -DateTimeOriginal \
-EXIF:FocalPlaneXResolution \
-EXIF:FocalPlaneYResolution "${f}") )
# check number of items in array. There will never be a 2 category
case ${#exifdata[@]} in
0)
# could not get DateTimeOriginal so wing it with creation (Birth) date
CD="$(stat -t '%Y%m%d%H%M%S' -f '%SB' "${f}")"
exifdata=(${CD} 0000 0000)
;;
1)
# got DateTimeOriginal but no FocalPlaneResolution data
exifdata+=(0000 0000)
;;
3)
# If FocalPlaneResolution is floating point,round to nearest integer
[[ ${exifdata[2]} =~ "." ]] && exifdata[2]=$(printf "%.0f" ${exifdata[2]})
[[ ${exifdata[3]} =~ "." ]] && exifdata[3]=$(printf "%.0f" ${exifdata[3]})
;;
*)
# should not get here as won't get just two items
continue
;;
esac
# yyyymmddHHMMSS fx fy seq
# 20200530221158|6532|6532|_001
# the (j) concatenates the three array elements as one string
# deleted from below to stop sequencing
TPLATE=${f:a:h}/${(j::)exifdata}_${nseq}
: <<'COMMENT'
# reset assoc array and duplicates counter when child folder changes
if [[ $curdir != $prevdir ]]; then
dupecnt=0
fi
COMMENT
# get 40 character SHA checksum from current file
dkey=$(shasum -a1 "${f}" | cut -d ' ' -f1) 2> /dev/null
# check if current file is a duplicate by key lookup
# use not (!) because non-duplicate branch will improve speed
if [[ ! ${dx[(k)$dkey]} ]]; then
# non-duplicate processing
OUTFMT="${TPLATE}.${f:e}"
# push new key/value pair with SHA key and original filename with delimiter
dx+=( $dkey "|${OUTFMT} => ${f}" )
else
# duplicate file processing
# return the count of duplicate filenames, excluding original file
dupecnt=$(( ${(ws:|:)#dx[(k)$dkey]} - 1))
(( dupecnt++ ))
OUTFMT="${TPLATE}-${dupecnt}.${f:e}"
# add filename to key's list of duplicate names
dx[$dkey]+="|${OUTFMT} => ${f}"
fi
# rename the image
mv "${f:a}" ${OUTFMT}
done
rpt_writer
# release associative array storage
dx=()
exit