|
#!/usr/bin/perl -w
##---------------------------------------------------------------------------##
#
# Program: jtouchdir
# Author: Brian <genius@groupbcl.ca> :)
# Date: 1 January 2010
#
# Sets the mtime on a directory based on its contents.
#
# For each directory name given, gets a lists of files in the directory,
# orders them according to extension, determines the most common extension,
# determines the timestamp of the most recently modified file of all the
# files that share that extension, then sets the modification timestamp of
# the directory to that time.
#
# For example, running 'jtouchdir' on a directory containing mostly JPEG
# files, the timestamp on the directory itself will be set to the same
# value as the most recent JPEG file in the directory.
#
##---------------------------------------------------------------------------##
# January 2010 Initial Version
# April 2012 Added -r (recursive)
##---------------------------------------------------------------------------##
# BUUS: This script is part of Brian's Useful Utilities Set
use strict;
die "usage: jtouchdir [-r] directory [directory ...]\n" if ! $ARGV[0];
my $recursive = 0;
$recursive=1, shift if $ARGV[0] eq '-r';
foreach my $dn (@ARGV) {
warn "$dn: not a directory", next if ! -d $dn;
warn "$dn: cannot read", next if ! -r $dn;
touch_dir($dn);
}
sub touch_dir {
my $dn = shift;
my @subdir_list;
my %exts; # Key = extension data = aref:
# [0]=counter, [1]=highest mtime. [2]=file with that mtime
my ($hcount, $hcount_ext) = (0, '');
my $dh;
opendir $dh, $dn or die "Unable to open directory '$dn' for reading: $!";
while (my $fn = readdir $dh) {
next if $fn eq '.' || $fn eq '..';
next if ! -f "$dn/$fn" && ! -d "$dn/$fn"; # Consider only files and sub-dirs
my $is_dir = -d "$dn/$fn" ? 1 : 0;
my $ext;
if ($is_dir) {
$ext = '__DIR__';
} else {
$ext = '__NONE__';
$ext = $1 if ! $is_dir && $fn =~ /\.([^\.]+)$/;
}
touch_dir("$dn/$fn") if $is_dir && $recursive;
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime,
$mtime, $ctime, $blksize, $blocks) = stat("$dn/$fn");
if (exists $exts{$ext}) {
$exts{$ext}[0]++;
$exts{$ext}[1] = $mtime, $exts{$ext}[2] = $fn if $mtime > $exts{$ext}[1];
} else {
$exts{$ext} = [ 1, $mtime, $fn ]
}
$hcount_ext = $ext, $hcount = $exts{$ext}[0] if $exts{$ext}[0] > $hcount;
# print " $fn (mtime=$mtime) --> $ext: $exts{$ext}[0], $exts{$ext}[1] | hcount=$hcount, hcount_ext=$hcount_ext\n";
}
closedir $dh;
if ($hcount_ext) {
my $fn = $exts{$hcount_ext}[2];
print "$dn: touching directory based on ", -d "$dn/$fn" ? 'subdirectory' : 'file', " '$fn'\n";
utime $exts{$hcount_ext}[1], $exts{$hcount_ext}[1], $dn;
} else {
print "$dn: unable to determine most recent common file (is directory empty?)\n";
}
}
# vim: tabstop=4
|