How to make all video files in a directory have a uniform naming format

The title for this page is a bit confusing, but the idea is simple. Rename all video files to standard format or style. If you download TV episodes from different sources they often use different naming styles and formats. This can be very annoying. For example:


 * The.Good.Guy.S01E01.HDTV.XviD-LOL.[VTV].avi
 * The Good Guy S01-E02 - the math test - HDTV XviD-2HD.avi
 * the good guy - 1x03 - happy days.avi
 * The_Good_Guy_-_S01_E04_-_HDTV_XviD.avi

The following script renames the files to follow a standard format.

Features

 * Removes all special characters
 * Replaces all spaces and underscores with periods
 * Removes common tags, ex HDTV, XviD, LOL, [VTV], DIVX, ...
 * Makes all characters lowercase
 * Renames only video files


 * Flaws
 * Cannot fix problems like the following
 * if the real title is 'The Good Guy' and some files use 'The Goodguy'
 * This can be manually fixed by adding a line to 'sub renamer' like the following. (use \. as spaces)
 * $oldname =~ s/the\.goodguy/the.good.guy/;

Standard format used

 * [title].[season][episode].[episode name].[extension]
 * Example: the.good.guy.0103.happy.days.avi

Examples

 * Original files
 * The.Good.Guy.S01E01.HDTV.XviD-LOL.[VTV].avi
 * The Good Guy S01-E02 - the math test - HDTV XviD-2HD.avi
 * the good guy - 1x03 - happy days.avi
 * The_Good_Guy_-_S01_E04_-_HDTV_XviD.avi


 * Renamed files
 * the.good.guy.0101.avi
 * the.good.guy.0102.the.math.test.avi
 * the.good.guy.0103.happy.days.avi
 * the.good.guy.0104.avi

Script

 * 1) !/usr/bin/perl


 * 1) Name: Video filename uniformalizer
 * 2) Version: 0.3
 * 3) Creator: Jeff Israel
 * 4) Date: 12 Jan, 2010
 * 5) License: GPL 3.0
 * 6) Description: This script renames files in a dir to a standard
 * 7)  format
 * 8) Requirements: perl
 * 9) Usage: video_filename_uniformalizer.pl [video directory]
 * 10) Example: video_filename_uniformalizer.pl /pub/video/tv/castle/
 * 11) Output naming format: [title].[season][episode].[episode name].[extension]
 * 12) Example: the.good.guy.0102.the.math.test.avi
 * 1) Output naming format: [title].[season][episode].[episode name].[extension]
 * 2) Example: the.good.guy.0102.the.math.test.avi
 * 1) Example: the.good.guy.0102.the.math.test.avi


 * 1) Configure
 * 1) Configure

$test = 0;

@fileExt = ("avi","rm","mpg","mpeg","asf","ram","wmv","mp4","ogg",'ogm',"m4v","mkv",'rmvb','mov','divx');

@commonRemoval = ('-sfm-','0tv','2hd','[0-9][0-9][0-9]kbps','\(1\)','\(1\)','\(ipod\)','\[bt\]','\[fixed\]','\[tvm\]','\[vpc\]','\[vtv\]','\{c_p\}','a4e','aaf','ac3','avi_sm','digitaldistractions','divx','divx-svm','divx5.1.1','divx_tv','dsr_loki','dsr_lol','dsr_umd','dsrip','dsrip-0tv','dsrip-0tv','dsrip-stfu','dvdrip','dvdrip','eztv','fqm\.sharconnector','h264','hdtv','hdtv-2hd','hdtv-aaf','hdtv-bia','hdtv-ctu','hdtv-ctu','hdtv-fqm','hdtv-lol','hdtv-xor','hdtv-yestv','hqtv','ipod_mpg','ipod_mpg4','ipodnova\.net','ipodnova\.tv','ipodnova_net','ipodnova_tv','ipodtvnova\.com','irc\.tveps\.net','niteshdw','pdtv','pdtv-angelic','pdtv-lol','pdtv-river','pdtv-saints','pdtv\.sfm','proper_hdtv','spcomplete_com','spepisode','tvrip','videoseed\.com','videoseed_com','www\.mrtwig\.net','www\.southparkx\.net','x264','xor','xvid-0tv','xvid-2hd','xvid-aaf','xvid-angelic','xvid-fov','xvid-river','xvid-sfm','xvid-stfu','xvid-xor','xvid','yestv','yg_divx4s');

if($ARGV[0] eq ""){ print "the first arg is the directory\n"; exit; }

sub isVideo { # doo my $filename = $_[0]; foreach $ext (@fileExt) { if ($filename =~ /$ext$/i) { return 1; } else { }	}	0; } sub renamer { # poo my $oldname = $_[0]; $oldname =~ s/[-_,\'\[\]\(\)\.\s]/./g; #all special chars to. $oldname =~ tr/A-Z/a-z/; #lowercase foreach $removal (@commonRemoval) { #remove all the common tags $oldname =~ s/\.($removal)\././i; }
 * 1) 			print "$ext: $filename: match\n";
 * 1) 			print "$ext: $filename: no match\n";

$oldname =~ s/s0([0-9])e([0-9]{2})/.\1\2./; # s01e01 to 101 $oldname =~ s/\.([0-9]{1,2})x([0-9]{2})\./.\1\2./; # 1x01 to 101 $oldname =~ s/s([0-9]{2})\.e([0-9]{2})/.\1\2./;	# s10_e01 to 1001 $oldname =~ s/s([0-9]{2})e([0-9]{2})/.\1\2./; # s10e01 to 1001 $oldname =~ s/\.([0-9]{3})\./.0\1./; # 101 to 0101

# I removed this because of bug listed below, now use method above # $oldname =~ s/\.([0-9])x([0-9]{2})\./.s0\1e\2./; # 1x01 to s01e01 # $oldname =~ s/\.([0-9]{2})x([0-9]{2})\./.s\1e\2./; # 11x01 to s11e01 # $oldname =~ s/s([0-9]{2})\.e([0-9]{2})/.s\1e\2./;	# s10.e01 to s10e01 # $oldname =~ s/([0-9]{2})([0-9]{2})/.s\1e\2./;	# 1101 to s11e01 # $oldname =~ s/([0-9])([0-9]{2})/.s0\1e\2./;	# 101 to s01e01 # one bug, if title is Castle 1990 103, it would switch to s19e90

# $oldname =~ s/^([0-9])/south_park_\1/; for ($x=0;$x<=$#findit;$x++){ $oldname =~ s/@findit($x)/@replaceit($x)_/i; # print "peep-"; }

#some personal stuff $oldname =~ s/\.avi\.avi$/.avi/; $oldname =~ s/\.sm\.avi$/.avi/; $oldname =~ s/southpark/south_park/; if($oldname =~ /^house\.[0-9]/ ){ $oldname =~ s/^house/house.md/; }	# $oldname =~ s/south_park([0-9])/south_park_\1/; $oldname =~ s/\.+/\./g; # removes double dots $oldname =~ s/^\.//; # removes initail dots $oldname; }

sub reext { my $fname = $_[0]; $fname =~ s/_([a-z0-9]{2,4})$/\.\1/; $fname; }

print "Starting the renaming\n";

opendir(DIR, "$ARGV[0]"); $x = 0; @file_list = ; while (defined($dir = readdir(DIR))) { if ( $dir ne '.' && $dir ne '..' && not -d $dir ) { $file_list[$x] = $dir; $x++; } } closedir(DIR);
 * 1) 	print "$dir";

foreach $dir (@file_list){ if ( isVideo($dir) ) {

# print "---$dir\n"; $newname = renamer($dir); $newnewname = reext($newname);

if ( $dir ne $newnewname ) { print "Moving:\n$dir\nTo:\n$newnewname\n\n"; if(!$test) { system("mv \"$ARGV[0]/$dir\" \"$ARGV[0]/$newnewname\""); }	} else { print "File: $dir\n"; print "No change needed.\n\n"; } } else { print "File: $dir\n"; print "non-video file\n\n"; }	}

print "\n";