Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Sort files into date-labeled subfolders using Perl UNIX
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. 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!).
    •    
  • Currently 1.75 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (4 votes cast)
 
[12,738 views]  

Sort files into date-labeled subfolders using Perl | 5 comments | Create New Account
Click here to return to the 'Sort files into date-labeled subfolders using Perl' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Sort files into date-labeled subfolders using Perl
Authored by: CarlRJ on Feb 25, '08 10:35:02AM

Hmm, for what it's worth, the stat function in the script needlessly performs a second stat(2) system call; the previous "-f" has just done a stat and left the results conveniently sitting around, all error-checked and safe and ready for our use, via the special "_" filehandle. Quoting perlfunc(1):

If any of the file tests (or either the "stat" or "lstat" operators) are given the special filehandle consisting of a solitary underline, then the stat structure of the previous file test (or stat operator) is used, saving a system call.

Thus:

my $mtime = (stat $name)[9] or next;

can become:

my $mtime = (stat _)[9];

And despite what the article says, the script does have error checking on all the file IO, so it looks decently safe to me. It will, of course, cheerfully mass-change whatever directory you tell it to, but then... you told it to, and Unix assumes you know what you're doing.



[ Reply to This | # ]
Sort files into date-labeled subfolders using Perl
Authored by: merlyn on Feb 25, '08 12:22:38PM

I avoided the bizarre "_" mostly because it isn't really saving that much time on this one-off script. It's also one of the few things I invented for Perl, so I can avoid it when I want. :)

Also, the biggest risk of loss is that you might rename a file onto the same name in the subdir, losing one of the two files in the process, since it's perfectly legal to rename(2) to an existing name. I didn't check for that, but it would take only one more statement.



[ Reply to This | # ]
Sort files into date-labeled subfolders using Perl
Authored by: jaysoffian on Feb 25, '08 02:21:15PM
Why use the mtime, which could easily be incorrect, instead of the (IMO) more reliable date that's part of the filename itself?

BTW, it would've been a trivial modification to Organize iChat archive files by sender to refile by date, but this will do it off the filename and will also refile chats that were previously sorted by sender into 10.5-style date folders.


#!/usr/bin/perl -w

use strict;

my $PREVIEW = 1; # set to 0 to actually do it

sub mkdir_if_needed
{
	my ($dir) = @_;
	return if -e $dir;
	print "mkdir $dir\n";
	return if $PREVIEW;
	mkdir $dir;
}

sub rename_if_needed
{
	my ($src, $dst) = @_;
	return if -e $dst;
	print "$src -> $dst\n";
	return if $PREVIEW;
	rename $src, $dst;
}

# could use File::Find, but we're lazy
open(FIND, "find '$ENV{HOME}/Documents/iChats' -name '*.chat' -o -name '*.ichat'|");

while(<FIND>) 
{
	chomp;
	my ($base) = m|([^/]*)$|; 
	my ($date) = /on (\d{4}-\d\d-\d\d) at/;
	next unless $base and $date; 
	my $dstdir = "$ENV{HOME}/Documents/iChats/$date";
	my $dst = "$dstdir/$base"; 
	mkdir_if_needed($dstdir);
	rename_if_needed($_, $dst);
}


[ Reply to This | # ]
Sort files into date-labeled subfolders using Perl
Authored by: glgray on Mar 01, '08 06:19:06AM

Thanks for posting this script. I ran it and it work quite well except for 118 chats that didn't get filed. All these chats are dated October 25, 2003 or earlier. Is there some reason you can think of that it didn't organize these?

Thanks.



[ Reply to This | # ]
Sort files into date-labeled subfolders using Perl
Authored by: joey03 on Mar 01, '08 08:26:22AM

Couldn't this be done via applescript?



[ Reply to This | # ]