My first (useful) Ruby program

June 25th, 2011

Summary: Batch convert files with names like 25_06_2011 21_30.wav to names like 2011-06-25_2130_Saturday.wav.

I have a load of files with date/time-based file names in the format dd_mm_yyyy hh_mm.wav. I’d prefer these files to have a format that allowed them to be sorted in a directory in a meaningful way by the file name (i.e. yyyy-dd-mm). I also have a pet hate of file names containing spaces. It would also be useful to show the day of the week in the file name. So what I’d really like is a file name in the format yyyy-dd-mm_hhmm_<dayname>.wav.

In the past I’d have written a Perl script to rename a batch of files, but since I’ve been looking at Ruby recently it made sense to have a bash at doing this in Ruby.

Here’s the program I came up with:

1 #!/c/ruby/bin/ruby
2 # Created by Alistair Christie
3 # Date: 25 June 2011
4 # This is my first functional Ruby program.
5 # It's purpose is to take files in the current directory (if no arg supplied) -
6 # or files in the specified directory (argument on command line) -
7 # that match the pattern nn_nn_nnnn nn_nn.wav
8 # (i.e. iPod voice memos saved as WAV files: dd_mm_yyyy hh_mm.wav)
9 # copy them to an archive subdirectory
10 # and rename the originals yyyy-mm-dd_hhmm_<dayname>.wav
11
12 require 'date'
13 require 'fileutils'
14
15 if ARGV.length > 0
16     $input_directory = ARGV[0]
17 else
18     $input_directory = '.'
19 end
20
21 Dir.chdir($input_directory)
22
23 $archivedir = "originalFiles_nowRenamed"
24 $count = 0
25
26 puts "Processing ..."
27
28 def file_match(pattern=/\d\d_\d\d_\d\d\d\d \d\d_\d\d\.wav/, path='.')
29   Dir[File.join(path,'*')].each do |file|
30     if file =~ pattern
31         $count += 1
32         if $count==1 then Dir.mkdir($archivedir) unless File.exists?($archivedir)
33         end
34         file =~ /^[^\d]*(\d\d)_(\d\d)_(\d\d\d\d) (\d\d)_(\d\d)/
35         #puts "Matched file: #{file}"
36         dt = Date.new($3.to_i, $2.to_i, $1.to_i);
37         dy = Date::DAYNAMES[dt.wday]
38         newfilename = "#$3-#$2-#$1_#$4#$5_" + dy + ".wav"
39         FileUtils.cp(file, $archivedir + "/" + file)
40         FileUtils.mv(file, newfilename)
41         puts file + " renamed " + newfilename
42     end
43   end
44 end
45
46 file_match
47
48 if $count>0 then puts $count.to_s + " files were renamed."
49 else puts "No files were renamed."
50 end
51

Anyone looking at this who knows how to code in Ruby will, doubtless, immediately see all sorts of issues with it. But I’m quite happy with it because it didn’t take long to write and it does the job.

I’ve saved this file as RenameWavFiles.rb in the iTunes directory where all these files get created and I have a shortcut to that directory so that all I need to do is click the shortcut icon to open the directory in Windows Explorer, then double-click the Ruby file to rename any new files. The files are copied to a subdirectory with their original names just in case there’s a problem. Job done!

I wrote the code in Vim 7.2 and one nice thing about the GVim incarnation of Vim is that, in the Syntax menu, there’s a Convert to HTML option that creates the output you can see above.

gvim-convert-to-HTML

Leave a comment