Organize your pictures by EXIF tags with bash
Just a simple script to order your thousands of pictures by putting them in subdirectories on the basis of EXIF shot date:
#!/bin/bash
# BashButler 1.0 - 11/2007 by Eugenio Rustico
# Bash script to organize your pictures in folders by date
#
# GPL v3 license http://www.gnu.org/licenses/gpl-3.0.html
ls -1 *.jpg | while read fn
do
export dt=`exiv2 "$fn" | grep timestamp | awk '{ print $4 }' | tr ":" "-"`
if test ! -e ./$dt
then
mkdir $dt
fi
mv "$fn" ./$dt
echo File "$fn" moved in "$dt"
done
echo Good job!
I wrote it to setup 4.900 pictures which were all in the same directory, and it was really fast and useful. My unstoppable sense of humor conceived this amazing script name: Bash Butler. I'm very sorry for this. =)
Notes:
- Of course you need exiv2 package on your system, but you can use other cli exif tools by modifying only one row;
- With very little changes, you can modify the script to organize your pictures by different EXIF tags (e.g. different folders for different digital cameras);
- Filenames with spaces are treated correctly;
- By default mv does'nt overwrite destination files: so all remaining files in current directory are copies, and can be deleted.
9 comments:
Thanks, just what I was looking for... so simple.
Really many thanks. This is exactly what I was looking for.
Here is an enhanced version: organize
#!/bin/bash
# PictureRenamer 1.0 - 08/2009 by Kaan Atasever
# This script renames your pictures with date and time
#
# GPL v3 license http://www.gnu.org/licenses/gpl-3.0.html
ls -1 *.jpg | while read fn
do
export pa1=`exiv2 "$fn" | grep timestamp | awk '{ print $4 }' | tr ":" "-"`
export pa2=`exiv2 "$fn" | grep timestamp | awk '{ print $5 }' | tr ":" "-"`
export pa="$pa1 $pa2.jpg"
mv "$fn" "$pa"
echo File "$fn" renamed as "$pa"
done
echo All done!
Be careful if you have pics taken within same second - the script as it is now will overwrite all but the last one.
Can someone help me with this? The folders I want to run this on are on an external. How do I point the script to the external. Which parts specifically do I paste into Terminal? Thanks
@Anonymous this scripts acts in the current directory, just CD to the directory where the drive is mounted (e.g. "cd /media/user/usbstick").
For anyone that come to this commen thread, here is an updated version that handles images that doesn't contain EXIF data
#!/bin/bash
# MediaRenamer 2.0 - Enhanced version
# This script renames image and video files based on their metadata creation date,
# and adds a "no_data_" prefix for files without metadata.
#
# GPL v3 license http://www.gnu.org/licenses/gpl-3.0.html
# List of supported file extensions for images and videos
media_extensions=("*.jpg" "*.jpeg" "*.png" "*.gif" "*.heic" "*.mp4" "*.3gp" "*.mov" "*.m4v" "*.mp")
# Loop through the specified file types
for ext in "${media_extensions[@]}"; do
for fn in $ext; do
# Skip if no files match the current extension
[ -e "$fn" ] || continue
# Extract creation date metadata using exiftool
creation_date=$(exiftool -CreateDate "$fn" | awk -F': ' '{print $2}')
if [ -n "$creation_date" ]; then
# If creation date is available, format it
formatted_date=$(echo "$creation_date" | sed 's/:/-/g' | awk '{print $1 " " $2}')
new_name="${formatted_date}.${fn##*.}"
mv "$fn" "$new_name"
echo "File \"$fn\" renamed as \"$new_name\""
else
# If no creation date, rename file with "no_data_" prefix
new_name="no_data_$fn"
mv "$fn" "$new_name"
echo "File \"$fn\" renamed as \"$new_name\""
fi
done
done
echo "All done!"
An improvement after 17 years from the original post... I'm moved :'-) I appreciate it, man.
Post a Comment