09.23
One of the most annoying things with mp3’s (other than DRM of course) is consecutive numbering. The sort algorithm on Windows and most mp3 players sorts as it goes through the filename one character at a time. So if you have 12 files named “file-1.mp3 … file-12.mp3″, they will sort like this:
file-1.mp3 file-10.mp3 file-11.mp3 file-12.mp3 file-2.mp3 file-3.mp3 file-4.mp3 file-5.mp3 file-6.mp3 file-7.mp3 file-8.mp3 file-9.mp3
That is obviously not what anybody wants. To correct this, consecutively numbered files must be zero-padded in order to sort correctly. So the previous list would need to look like this:
file-01.mp3 file-02.mp3 file-03.mp3 file-04.mp3 file-05.mp3 file-06.mp3 file-07.mp3 file-08.mp3 file-09.mp3 file-10.mp3 file-11.mp3 file-12.mp3
I run into this problem often enough that I started looking around for software that would pad the numbers in filenames automatically for me. I couldn’t find anything out there that would do it in an automated fashion so I wrote a perl script to do it. I wrote it in Perl so that I could run it under Linux as well. I frequently need to have jpeg’s consecutively numbered as well so that was important. Here is the script:
#!/usr/bin/perl
use strict;
use warnings;
my $dirname = $ARGV[0] || "";
my $change = $ARGV[1] || "no";
my $ext = $ARGV[2] || ".mp3";
my $padsize = $ARGV[3] || 4;
##: Give usage if no arguments are defined
if ($dirname eq "") {
print STDOUT "Usage: numpad.pl \"directory\" [change?] [.ext] [padsize]\n";
print STDOUT " [change?] - default is \"no\" - should I actually rename the file\n";
print STDOUT " [.ext] - default is \".mp3\" - what files should be acted upon\n";
print STDOUT " [padsize] - default is \"4\" - how many digits should I pad to\n";
print STDOUT "\n";
print STDOUT "Example:\n";
print STDOUT " numpad.pl \"c:\\mp3\\album\" yes .wav 5\n";
exit(1);
}
##: Change to the directory asked for
chdir($dirname) or die "Couldn’t change to directory ’$dirname’: $!";
##: Open and read in the directory based on the fileglob given
opendir(DIR, "$dirname") or die "Couldn’t open directory ’$dirname’: $!";
my @files = grep { /.*$ext/ } readdir(DIR);
closedir DIR;
##: Loop through the file entries and mod them
foreach my $file (@files) {
my $newfilename="";
##: Cut off the extension, to be put back on later
$file =~ s/$ext//g;
##: Split the filename into an array using any number as a separator
my @fnparts = split(/([0-9]*)/, $file);
##: Loop through the array and pad any numerical elements
foreach (@fnparts) {
my $result = $_;
my $number = 0;
if($result =~ m/[0-9]+/) {
$number = sprintf("%0".$padsize."d", $result);
$newfilename.=$number;
} else {
$newfilename.=$result;
}
}
$newfilename.=$ext;
$file.=$ext;
print STDOUT "$file\n -> $newfilename\n";
if($change eq "yes") {
rename($file, $newfilename);
}
}
Just save this code as a file named numpad.pl. If you run it on Windows, you will have to either install a perl interpereter first(get the MSI package from ActiveState) or download the native executable version below that was compiled with Perl2Exe. If you use the interpreter method you would need to execute perl and pass the script name to it as the first argument. Like this:
c:\> perl numpad.pl "c:\mp3\album" yes .wav 5
That example would zero-pad all the files in the c:\mp3\album directory that end with .wav, making any number it finds in a filename at least 5 digits long. This script should handle any files you give it; not just mp3’s. You can also re-run it with a different padding amount and it will redo the padding if you put too many on the first time. If you tell it “no” as the second argument, it will just show you what it would do instead of actually doing it. As always, USE AT YOUR OWN RISK!
- Native Exe Version: numpad.exe
- Perl Source Version: numpad








