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.

[topads][/topads]

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

GitHub Repo

Have fun 🙂

[bottomads][/bottomads]

Spread the love

3 thoughts on “Script to Rename Files in UNIX / Linux

  1. Orm says:

    Looks interesting. I searched for a good coomand line file renamer
    a while ago. At that time I ended up using mmv:
    http://linux.dsplabs.com.au/mmv-copy-append-link-move-multiple-files-under-linux-shell-bash-by-wildcard-patterns-p5/

    • jgezau says:

      That looks interesting. Will have to look into it more and see if it fits my needs!! I decided to write my own since when I was doing my research I could not find a script that would fit my needs…

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.