Fancy rtouch

2009-03-09

Well, it turns out Ruby’s library functions for touch don’t let you specify a modification time; you can set the file to the current time only. I could just call out to the touch binary, but that wouldn’t be very portable. So I’m back to Perl. Here is the program with a -t [[CC]YY]MMDDhhmm[.SS] option, just like touch(1):

#!/usr/bin/perl -w
use strict;
use File::Find;
use Getopt::Std;
use Time::Local;

my $mtime;
my %opts;
getopts('ht:', \%opts);

if ($opts{h}) {
  usage();
  exit 0;
}

if ($opts{t}) {
  if ($opts{t} =~ m/(\d\d\d\d|\d\d)?(\d\d)(\d\d)(\d\d)(\d\d)(\.(\d\d))?/) {
    my @now = localtime;
    my $cent = $now[5] + 1900;
    my $secs = $now[0];
    if ($1) {
      if (length $1 > 2) {
        $cent = $1;
      } else {
        $cent = 100 * int($cent / 100) + $1;
      }
    }
    if ($7) {
      $secs = $7;
    }
    @now = ();
    $now[0] = $secs;		# seconds
    $now[1] = $5;		# minutes
    $now[2] = $4;		# hours
    $now[3] = $3;		# day of the month
    $now[4] = $2 - 1;		# month (0..11)
    $now[5] = $cent - 1900;	# years since 1900

    $mtime = timelocal(@now);
  } else {
    usage();
    exit 1;
  }
} else {
  $mtime = time;
}

for my $dir (@ARGV ? @ARGV : ('.')) {
  if (-e $dir) {
    find sub {
      utime $mtime, $mtime, $_;
    }, $dir;
  } else {
    open NOTHING, ">$dir";
    close NOTHING;
    utime $mtime, $mtime, $dir;
  }
}

sub usage {
  print "USAGE: $0 [-t [[CC]YY]MMDDhhmm[.SS]] [files...]\n";
}

I debated whether rtouch should create nonexistent files. The regular touch command creates any files that don’t exist. But since rtouch is recursive, I’m not sure creating files makes sense. But I figured it could still be convenient, so you could give it a bunch of arguments with the intent, “Touch all these files and everything in them, creating empty files whenever one doesn’t exist.”

(In case you haven’t guessed, this week is spring break!)

blog comments powered by Disqus Prev: Simple Wordpress Hit Counter Plugin Next: rtouch