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
Have fun 🙂
[bottomads][/bottomads]
Shiloh Munoz liked this on Facebook.
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/
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…