Similar to “PowerShell – Rename Pictures to Image Taken“, this script will work on macOS and most Unix systems (Fedora/CentOS/Rocky/Red Hat (RHEL) and Ubuntu/Debian for example).
NOTE: This is an update to a previous posted version of this script. Both exist to provide some options. Previous post: BASH – Picture / Video File Name Manipulation
This script will:
- Ask if you want to assign a photographer to the picture, if not type nothing and press Enter/Return.
- If the provided name for the photographer is not alphanumeric each character will be replaced with an underscore so that the file name will work.
- Change capitalization of file extensions from JPG to jpg for example.
- Move any video files out of the directory to a separate directory
Bash
#!/bin/sh
# brew install imagemagick
# brew install exiftool
echo "Please type in the photographer name or simply press enter/return. "
read photographer
#region Pictures
#region Change Capitalization of Extensions
if [[ ! -z $(find . -type f -name "*.JPG") ]]; then
echo "Changing case of JPG to jpg"
for f in *.JPG; do
mv -vf "$f" "${f%.JPG}.jpg"
done
fi
if [[ ! -z $(find . -type f -name "*.jpeg") ]]; then
echo "Changing jpeg to jpg"
for f in *.jpeg; do
mv -vf "$f" "${f%.jpeg}.jpg"
done
fi
if [[ ! -z $(find . -type f -name "*.HEIC") ]]; then
echo "Changing case of HEIC to heic"
for f in *.HEIC; do
mv -vf "$f" "${f%.HEIC}.heic"
done
fi
if [[ ! -z $(find . -type f -name "*.NEF") ]]; then
echo "Changing case of NEF to nef"
for f in *.NEF; do
mv -vf "$f" "${f%.NEF}.nef"
done
fi
#endregion Change Capitalization of Extensions
# If a photographer is provided we will add an underscore and the name to the picture file.
# If the provided name has any spaces or characters that can not be a file name they are replaced.
if [ ! -z "$photographer" ]; then
# If photographer was provided, remove any characters from the string that are not alphanumeric
photo_photographer="_$(echo "$photographer" | sed 's/[^a-zA-Z0-9]/_/g')"
else
# If photographer was not provided
photo_photographer=""
fi
if compgen -G "*.jpg" >/dev/null || compgen -G "*.dng" >/dev/null || compgen -G "*.nef" >/dev/null; then
# File is a picture that should have exif data
# This first part will rename a picture based on the date and time the picture was taken.
# NOTE: This will only work properly if you have the original files. It usually will not work if you downloaded the pictures from social media or other sources.
mkdir -p DatedFiles/pictures
mkdir -p NoDateFiles/pictures
exiftool -r -d "%Y/%m/%Y-%m-%d_%H.%M.%s" '-FileName=NoDateFiles/%f%+c.%e' '-FileName<DatedFiles/${datetimeoriginal}_${imagesize}%-c.%e' -d "%Y-%m-%d_%H.%M.%S" .
# This part will add the image size to the file name
find DatedFiles/. -name \*.jpg -o -name \*.dng >picture_files.txt
while IFS="" read -r picture || [ -n "$picture" ]; do
filename=$(basename -- "$picture")
extension="${filename##*.}"
filename="${filename%.*}"
# If photographer is defined then add it to the file name
# cp -v ${picture} "rename/pictures/${filename}_${photographer}.${extension}"
mv -v ${picture} "DatedFiles/pictures/${filename}${photo_photographer}.${extension}" # Once you are comfortable with the copy results you can comment/remove the copy and uncomment the move
done <picture_files.txt
rm -fv picture_files.txt
find NoDateFiles/. -name \*.jpg -o -name \*.dng >picture_files.txt
while IFS="" read -r picture || [ -n "$picture" ]; do
filename=$(basename -- "$picture")
extension="${filename##*.}"
filename="${filename%.*}"
# cp -v ${picture} "rename/pictures/${filename}_${photographer}.${extension}"
mv -v ${picture} "NoDateFiles/pictures/${filename}${photo_photographer}.${extension}" # Once you are comfortable with the copy results you can comment/remove the copy and uncomment the move
done <picture_files.txt
rm -fv picture_files.txt
fi
#endregion Pictures
# region AVI, MP4, MOV
if compgen -G "*.avi" >/dev/null || compgen -G "*.mp4" >/dev/null || compgen -G "*.mov" >/dev/null; then
find . -name \*.avi -o -name \*.mp4 -o -name \*.mov >video_files.txt
while IFS="" read -r video || [ -n "$video" ]; do
# Try to create a rename directory
mkdir -p rename/videos
filename=$(basename -- "${video}")
extension="${filename##*.}"
filename="${filename%.*}"
newname="${filename}${photo_photographer}"
echo "Original Name: ${video}"
echo "New Name: $newname.${extension}"
# cp -v "${video}" "rename/videos/${newname}.${extension}"
mv -v "${video}" "rename/videos/${newname}.${extension}" # Once you are comfortable with the copy results you can comment/remove the copy and uncomment the move
done <video_files.txt
rm -fv video_files.txt
fi
# endregion AVI, MP4, MOV
#region Cleanup Empty Files/Directories
find . -depth \( -name "Thumbs.db" -o -name "desktop.ini" -o -name ".DS_Store" -o -name "._*" -o -name "SyncToy*.dat" -o -name "Picasa.ini" \) -type f -exec rm -rfv {} \;
# Remove empty files in general before delete empty directories
find . -depth -empty -type f -exec rm -rfv {} \;
# Delete empty directories
#find . -depth -empty -type d -delete
find . -depth -empty -type d -exec rm -rfv {} \;
#endregion Cleanup Empty Files/Directories
Originally Posted on June 21, 2025
Last Updated on October 15, 2025
Last Updated on October 15, 2025
All information on this site is shared with the intention to help. Before any source code or program is ran on a production (non-development) system it is suggested you test it and fully understand what it is doing not just what it appears it is doing. I accept no responsibility for any damage you may do with this code.