FilenameUnifier

Version: v0.2

Summary: Ever wanted to mass rename a bunch of files into a specific pattern based on their original filenames? Yeah, there are other utilities out there, but this is a simple solution based on my FilenameSanitizer script which locates filenames in a given directory with a specific pattern, and then renames them based on that pattern. As of the current version, it’s set to unify numeric .jpg images. For example, “5466.Jpeg” would become “005466.JPG”.

Requirements:

  • find
  • sed
  • wc
  • whoami

Code:

#!/bin/bash
 
LOG="${HOME}/.FilenameUnifier.log"
TMPLOG="/tmp/FilenameUnifier-`whoami`"
 
##Write Date & Time to Log File
echo "-------------------------------------" > "${LOG}"
echo "`date +%B %d, %Y`" >> "${LOG}"
echo "-------------------------------------" >> "${LOG}"
 
USAGE="Usage: ${0} -s "
 
echo "FilenameUnifier"
echo "Prototype by Kevin Warns"
echo "Modified by Blake Johnson"
echo "http://www.simplescripts.net/"
echo
 
while getopts 's:h' OPTION; do
	case ${OPTION} in
		s) SOURCE="${OPTARG}";;
		h) echo "${USAGE}" >&2
			exit 2;;
		?) echo "Unknown option "-${OPTARG}"." >&2
			echo ${USAGE};;
		:) echo "Option "-${OPTARG}" needs an argument." >&2
  			echo ${USAGE}
  			exit 2;;
  		*) echo ${USAGE}
  			exit 2;;
  	esac
done
 
if [ -z "$SOURCE" ]
then
	echo "One or more parameters are missing."
	echo "${USAGE}"
	exit 2
fi


find "${SOURCE}" -type f -regextype "posix-extended" -iregex ".*[/][0-9]{1,5}.jpe?g$" > "${TMPLOG}" 2>"${LOG}" ##Let's check for .jpg files with only numbers in their names.

UpperBound=$(cat "${TMPLOG}" | wc -l)  ##Count the number of results found.
 
if [ "${UpperBound}" = "0" ]  ##Check to make sure that 'find' found some files that need to be renamed.
then
	echo "There is nothing to rename."
	exit 1
else
	echo "${UpperBound} file(s) found."
	i=0
	e=0
	s=0
	while [ "${i}" -lt "${UpperBound}" ]
	do
		(( i += 1 ))
		TMPLINE=$(sed -n "${i}p" "${TMPLOG}")
		InputLocation="${TMPLINE%/*}"
		InputName="${TMPLINE##*/}"
 
		NewName="${InputName}"
		NewName=$(echo -n "${NewName}" | sed 's/jpe?g/JPG/i')  ##Strip leading spaces and trailing spaces / periods.

		FilenameLength=${#NewName} ##grab the # of characters in the filename

		#number of digits = length - 4 (accounting for .jpg)
		let COUNTER=$FilenameLength-4
		while [ $COUNTER -lt 6 ]; do
	   	 	NewName="0"${NewName}
			(( COUNTER += 1 ))
		done

		OutputPath="${InputLocation}/${NewName}"

		if [ "${OutputPath}" == "${TMPLINE}" ] ##Check to make sure that the name was actually changed.
		then
			echo -e ""${TMPLINE}" [ 33[1;31mNot Renamed33[0m ]"
			echo "Reason: Name Unchanged. This may be an error in the script."
		fi

		if [ -f "${OutputPath}" ] ##Check to make sure that the new name won't overwrite an existing file.
		then
			OutputPath="${OutputPath}.RENAME_${i}"
		fi

		echo -n "Renaming "${TMPLINE}" to "${OutputPath}"... "
		mv "${TMPLINE}" "${OutputPath}" >> "${LOG}" 2>&1
		echo "mv "${TMPLINE}" "${OutputPath}"" >> "${LOG}" 2>&1

		if [ "$?" == 0 ] ##Check to see if the 'mv' command failed or not.
		then
			echo -e "[ 33[1;32mRenamed33[0m ]"
			(( s += 1 ))
		else
			echo -e "[ 33[1;31mNot Renamed33[0m ]"
			(( e += 1 ))
		fi
		echo
		unset NewName OutputPath TMPLINE
	done

	echo "${s} / ${i} file(s) renamed successfully."
	echo "${e} file(s) could not be renamed."
fi
 
rm "${TMPLOG}" >> "${LOG}"
exit 0

Changes:
v0.2: Initial Release
v0.1: Prototype

Credits: Special thanks to Kevin Warns for creating a prototype for me to start off with.

Leave a Reply

Your email address will not be published.