Sort files into date-labeled subfolders using Perl

Feb 25, '08 07:30:04AM

Contributed by: robg

When I installed Leopard, I installed it to an empty partition using a clean install. I then manually migrate my older documents and settings over time -- it's not that I don't trust the Migration Assistant (well, I don't trust it completely, but that's another story), but that I look on each major OS X upgrade as the chance to clean house. So this weekend, after a slow migration, I decided it was finally time to zero out the old 10.4 partition ... but I had a slight problem.

I archive my iChats, and have done so for many years. In those archives, there's a ton of knowledge that I prefer to keep rather than lose, so I wanted to move the archived chats into my current iChats folder on the 10.5 disk. In 10.4, all iChat archives were stored at the top level of your user's Documents » iChats folder. In 10.5, however, archived chats are now sorted into subfolders based on the date of the chat. I wanted to move my huge archive to the 10.5 partition, but I didn't want to clutter the archives folder with thousands of files at the top level -- I wanted them sorted by date, as in 10.5.

I was pretty sure that Perl could make short work of this problem ... if only I knew Perl. Thankfully, I know someone who knows Perl; you might even say he wrote the book on it. Randal Schwartz (aka merlyn here on macosxhints.com) came to my rescue with a nifty bit of code he cobbled together while waiting for a flight.

With his (mostly, to me) unreadable code, the task of organizing 12,000+ iChat archives took but a couple minutes of run time. The code follows, but please read the warning that follows before trying it yourself.

#!/usr/bin/perl
use strict;
$|++;

my $DIR = "/path/to/ichat/archives/folder";
# By default, the path would be /Users/your_user/Documents/iChats

chdir $DIR or die "Cannot chdir $DIR: $!";
for my $name (glob '*') {
  next unless -f $name;
  my $mtime = (stat $name)[9] or next;
  my @stamp = localtime $mtime;
  my $date_dir =
    sprintf "%04d-%02d-%02d", $stamp[5]+1900, $stamp[4]+1, $stamp[3];
  -d $date_dir or mkdir $date_dir, 0777 or die "Cannot mkdir $date_dir: $!";
  print "mv $name $date_dir/$name... ";
  if (rename $name, "$date_dir/$name") {
    print "ok\n";
  } else {
    print "failed: $!\n";
  }
}
To use the script, copy and paste the above into a Terminal text editor such as nano or vi. There's one line you need to pay attention to: the my $DIR line. Edit the path shown on that line to reflect the location of your archived iChats. Save the script (ideally somewhere on your user's $PATH), make it executable (chmod a+x scriptname), and then (important!) back up your archived Chats folder -- just in case!

The script is very basic, and has no error checking of any sort -- make sure you set the correct path before you run it. Run it from anywhere, and it will spit out one line of output for each file it moves into a dated folder. Once it's done, select all the dated folders and drag them into your 10.5 iChats folder, and you're good to go. And yes, I realize I could have left the folder as it was and just moved it elsewhere before zeroing the drive ... but I wanted a consolidated iChats folder (for no good reason other than neatness!).

Comments (5)


Mac OS X Hints
http://hints.macworld.com/article.php?story=2008022420010324