#!/usr/bin/env perl # # lm - last modified file (including directories) # # $Id$ use strict; use warnings; use Getopt::Std; use File::Find; use POSIX qw(strftime); use List::Util qw(sum); no warnings 'File::Find'; my %opt; getopts( 'h?dfF:Lm:M:n:tT', \%opt ); if ( $opt{h} || $opt{'?'} ) { HELP_MESSAGE(); } sub HELP_MESSAGE { print STDERR < 1 ) { die "$0: specify at most one of the options -d, -f and -T\n"; } $opt{F} = '%f' if !defined $opt{F}; $opt{n} = 1 if !defined $opt{n}; foreach ( @ARGV ? @ARGV : '.' ) { list_last_modified_files($_); } sub list_last_modified_files { my ($arg) = @_; my @latest_filename = (); # the top n filenames my @latest_mtime = (); # the top n mtimes, in the same order find( { follow => $opt{L}, follow_skip => 2, wanted => sub { my $mtime = ( stat($_) )[9]; return if !defined($mtime); return if defined( $opt{m} ) && -M $_ > $opt{m}; return if defined( $opt{M} ) && -M $_ < $opt{M}; return if $opt{d} && !-d $_; return if $opt{f} && !-f $_; return if $opt{T} && !-T $_; my $filename = $File::Find::name; # insert the file into the top n, if it belongs there my $inserted = 0; for my $i ( 0 .. $#latest_filename ) { if ( $mtime > $latest_mtime[$i] ) { # insert this item splice( @latest_filename, $i, 1, $filename ); splice( @latest_mtime, $i, 1, $mtime ); $inserted = 1; last; } } if ( !$inserted && scalar(@latest_filename) < $opt{n} ) { push( @latest_filename, $filename ); push( @latest_mtime, $mtime ); } elsif ( $inserted && scalar(@latest_filename) > $opt{n} ) { pop(@latest_filename); pop(@latest_mtime); } } }, $arg ); for my $i ( 0 .. $#latest_filename ) { print_file( $latest_filename[$i], $latest_mtime[$i], $arg ); } } sub print_file { my ( $filepath, $mtime, $arg ) = @_; local ($_) = $opt{F}; my @lmtime = localtime($mtime); s/%a/$arg/g; s/%f/$filepath/g; s/%m\{([^}]*)}/strftime($1,@lmtime)/e; print "$_\n"; }