Hi everyone !
Please no bash-shaming
, I did my out most best to somehow put everything together and make it somehow work without any prior bash programming knowledge. It took me a lot of effort and time.
While I'm pretty happy with the result, I find the execution time very slow: 16min for 2288 files
.
On a big folder with approximately 50,062 files this would take over 6hours !!!
If someone could take a look and give me some easy to understand hints I would greatly appreciate it.
What Am I trying to achieve ?
Create a bash script that use exiftool
to stripe the date from images in a readable format (20240101) and compare it with an end_range
to order only images from that specific date range
(ex: 2020-01-01 -> 2020-12-30).
Also some images lost some EXIF data so I have to loop through specific time fields:
- DateTimeOriginal
- CreateDate
- FileModifyDate
- DateAcquired
The script in question
#!/bin/bash
shopt -s globstar
folder_name=/home/user/Pictures
start_range=20170101
end_range=20180130
for filename in $folder_name/**/*; do
if [[ $(/usr/bin/vendor_perl/exiftool -m -d '%Y%m%d' -T -DateTimeOriginal "$filename") =~ ^[0-9]+$ ]]; then
DateTimeOriginal=$(/usr/bin/vendor_perl/exiftool -d '%Y%m%d' -T -DateTimeOriginal "$filename")
if [ "$DateTimeOriginal" -gt $start_range ] && [ "$DateTimeOriginal" -lt $end_range ]; then
/usr/bin/vendor_perl/exiftool -api QuickTimeUTC -r -d %Y/%B '-directory<$DateTimeOriginal/' '-FileName=%f%-c.%e' "$filename"
echo "Found a value"
echo "Okay its $(tput setab 22)DateTimeOriginal$(tput sgr0)"
fi
elif [[ $(/usr/bin/vendor_perl/exiftool -m -d '%Y%m%d' -T -CreateDate "$filename") =~ ^[0-9]+$ ]]; then
CreateDate=$(/usr/bin/vendor_perl/exiftool -d '%Y%m%d' -T -CreateDate "$filename")
if [ "$CreateDate" -gt $start_range ] && [ "$CreateDate" -lt $end_range ]; then
/usr/bin/vendor_perl/exiftool -api QuickTimeUTC -r -d %Y/%B '-directory<$CreateDate/' '-FileName=%f%-c.%e' "$filename"
echo "Found a value"
echo "Okay its $(tput setab 27)CreateDate$(tput sgr0)"
fi
elif [[ $(/usr/bin/vendor_perl/exiftool -m -d '%Y%m%d' -T -FileModifyDate "$filename") =~ ^[0-9]+$ ]]; then
FileModifyDate=$(/usr/bin/vendor_perl/exiftool -d '%Y%m%d' -T -FileModifyDate "$filename")
if [ "$FileModifyDate" -gt $start_range ] && [ "$FileModifyDate" -lt $end_range ]; then
/usr/bin/vendor_perl/exiftool -api QuickTimeUTC -r -d %Y/%B '-directory<$FileModifyDate/' '-FileName=%f%-c.%e' "$filename"
echo "Found a value"
echo "Okay its $(tput setab 202)FileModifyDate$(tput sgr0)"
fi
elif [[ $(/usr/bin/vendor_perl/exiftool -m -d '%Y%m%d' -T -DateAcquired "$filename") =~ ^[0-9]+$ ]]; then
DateAcquired=$(/usr/bin/vendor_perl/exiftool -d '%Y%m%d' -T -DateAcquired "$filename")
if [ "$DateAcquired" -gt $start_range ] && [ "$DateAcquired" -lt $end_range ]; then
/usr/bin/vendor_perl/exiftool -api QuickTimeUTC -r -d %Y/%B '-directory<$DateAcquired/' '-FileName=%f%-c.%e' "$filename"
echo "Found a value"
echo "Okay its $(tput setab 172)DateAcquired(tput sgr0)"
fi
elif [[ $(/usr/bin/vendor_perl/exiftool -m -d '%Y%m%d' -T -ModifyDate "$filename") =~ ^[0-9]+$ ]]; then
ModifyDate=$(/usr/bin/vendor_perl/exiftool -d '%Y%m%d' -T -ModifyDate "$filename")
if [ "$ModifyDate" -gt $start_range ] && [ "$ModifyDate" -lt $end_range ]; then
/usr/bin/vendor_perl/exiftool -api QuickTimeUTC -r -d %Y/%B '-directory<$ModifyDate/' '-FileName=%f%-c.%e' "$filename"
echo "Found a value"
echo "Okay its $(tput setab 135)ModifyDate(tput sgr0)"
fi
else
echo "No EXIF field found"
done
Things I have tried
- Reducing the number of
if
calls
But it didn't much improve the execution time (maybe a few ms?). The syntax looks way less readable but what I did, was to add a lot of or ( || ) in the syntax to reduce to a single if
call. It's not finished, I just gave it a test drive with 2 EXIF fields (DateTimeOriginal and CreateDate) to see if it could somehow improve time. But meeeh :/.
#!/bin/bash
shopt -s globstar
folder_name=/home/user/Pictures
start_range=20170101
end_range=20201230
for filename in $folder_name/**/*; do
if [[ $(/usr/bin/vendor_perl/exiftool -m -d '%Y%m%d' -T -DateTimeOriginal "$filename") =~ ^[0-9]+$ ]] || [[ $(/usr/bin/vendor_perl/exiftool -m -d '%Y%m%d' -T -CreateDate "$filename") =~ ^[0-9]+$ ]]; then
DateTimeOriginal=$(/usr/bin/vendor_perl/exiftool -d '%Y%m%d' -T -DateTimeOriginal "$filename")
CreateDate=$(/usr/bin/vendor_perl/exiftool -d '%Y%m%d' -T -CreateDate "$filename")
if [ "$DateTimeOriginal" -gt $start_range ] && [ "$DateTimeOriginal" -lt $end_range ] || [ "$CreateDate" -gt $start_range ] && [ "$CreateDate" -lt $end_range ]; then
/usr/bin/vendor_perl/exiftool -api QuickTimeUTC -r -d %Y/%B '-directory<$DateTimeOriginal/' '-directory<$CreateDate/' '-FileName=%f%-c.%e' "$filename"
echo "Found a value"
echo "Okay its $(tput setab 22)DateTimeOriginal$(tput sgr0)"
else
echo "FINISH YOUR SYNTAX !!"
fi
fi
done
- Playing around with find
To recursively find my image files in all my folders I first tried the find
function but that gave me a lot of headaches... When my image file name had some spaces in it, it just broke the image path strangely... And all answers I found on the web where gibberish and I couldn't make it work in my script properly... Lost over 4 yours only on that specific issue !
To overcome the hurdle someone suggest to use shopt -s globstar
with for filename in $folder_name/**/*
and this works perfectly. But I have no idea If this could be the culprit of slow execution time?
- Changing all
[ ]
into [[ ]]
That also didn't do the trick.
How to Improve the processing time ?
I have no Idea if it's related to my script or the exiftool call that makes the script so slow. This isn't that much of a complicated script, I mean, it's a comparison between 2 integers not a hashing of complex numbers.
I hope someone could guide me in the right direction :)
Thanks !