Script to Rename Files in UNIX / Linux

This is a simple script that will rename files. Takes an absolute path as input, and looks for files with a specific string in its name. Will not traverse up the specified path. It will keep a log of the last run in the script’s directory.

I have more than 500 files that need to be renamed, but I am too lazy to do it manually, so I wrote this script to do it for me. All of the files follow two specific patterns in the name as indicated below.






Update: 20130629 – Refactored the code to make it more efficient. Not using helper files anymore, nor arrays.

Pattern 1: Name of Show – Episode Title
Pattern 2: Name of Show – 01 – Episode Title

What I wanted to do is get rid of the first part of the name up to the dash (-) [or last dash in pattern 2] since I have the files in different directories according to show name, so the name of the show in the file name is not needed.

You can download the script at the bottom of this post. The zip includes current and previous version.

Usage

$ ./rename.sh "/home/jgezau/Audio/show"

You must provide the script with an absolute path as input enclosed in “quotation” marks and omit the last forward-slash (/). The script will make sure you provide an absolute path and that the input directory actually exists.

Below is the script to accomplish this. I will explain some of the used commands.

#!/bin/bash
##############################################################################
# Simple script that will rename files. 
# Takes an absolute path as input, and looks for files with a specific string in its name. Will not
# traverse up the specified path. It will keep a log of the last run in the script's directory.
# 
# Author: jgezau
# Version 1.0
# 
# Usage:
# $ ./rename.sh "/full/path/to/files"
##############################################################################

# Variables
path=$1
strToSearch="[Tt]itle [Oo]f [Ss]how - "
strToMatch=" -"
strToMatch=" -"
logFile="log.txt"

abs=$(echo "$path" | cut -c1 )
thisDir=$(pwd)

if [[ $# -eq 0 ]]; then
	echo -e "** Provide an absolute path **"
	exit 1
elif [[ ! -d $path ]]; then
	echo "** Directory does not exists **"
	exit 1
elif [[ $abs != "/" ]]; then
	echo "** Not an absolute path **"
	exit 1
else
	# Change directory
	cd "$path"
	
	count=0
	echo -e "*** $(date) ***\n$path" >> "$thisDir/$logFile"
	
	old_IFS=$IFS		# Save the field separator
	IFS=$'\n'			# New field separator, the end of line
	
	# Check if log file was created
	if [[ ! -f "$thisDir/$logFile" ]]; then
		echo "** Could not create Log File **"
		echo "Do you wish to continue w/o Log File? (y/n)"
		read cont
		
		if [[ "$cont" == "y" ]]; then
			continue > /dev/null 2>&1
		else
			exit 0
		fi
	fi
	
	# Searching for files matching specific text
	for oldFName in $(find . -type f -maxdepth 1 -exec basename {} \; | grep "$strToSearch"); do
		newFName=$(echo "$oldFName" | awk -F"$strToMatch" '{if (NF>1) {print $NF}}' | sed 's:^ ::') 
		
		echo "Renaming '$oldFName' to '$newFName'"
		
		# Renaming Files
		echo mv "$oldFName" "$newFName" >> "$thisDir/$logFile"
		#mv "$oldFName" "$newFName"
		
		(( ++count ))
	done

	IFS=$old_IFS		# Restore default field separator
	
	echo "Renamed $count files"

	# Go back to previous directory
	cd -
fi

In Detail

strToSearch="[Tt]itle [Oo]f [Ss]how - "

This piece is key, grep command will use it to grab files containing this specific string in the file name. [Tt] will ensure to look for upper case or lower case letter “T”

for oldFName in $(find . -type f -maxdepth 1 -exec basename {} \; | grep "$strToSearch"); do

Finds all files in current directory, grabbing only files containing strToSearch string and getting the basename for each file. Will be saved in oldFName for the current file name.

strToMatch=" -"

This variable is the one that decides, “hey, I will be cutting up to here from the file name”. Is used by awk program to get the new file name.

newFName=$(echo "$oldFName" | awk -F"$strToMatch" '{if (NF>1) {print $NF}}' | sed 's:^ ::')  

Echoing the current file name, and creating the new file name.

The rest of the script should be self explanatory.

WARNING: I have to issue this warning. Before running this script, make sure you know what you are doing, this can give you undesired results. I have commented out the renaming command (mv) in line 64, please run the script first like this and look at the log file [which will be created in the same directory as the script], this will tell you exactly what it did, and if you are satisfied, then go ahead and uncomment line 64.

Get The Code

rename.zip includes the below files:

  • rename-0.1.sh
  • rename-1.0.sh

Have fun 🙂





Esau Silva
Software Engineer at Region One ESC
Microsoft Full Stack Application Developer
If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed.
Share