#!/usr/bin/perl -w # # $Id: glf,v 1.4 2009/03/10 13:23:06 jmates Exp $ # # Get latest file in a directory by mtime, optionally limiting the files # to those that match a particular regular expression, or also # optionally reading the filenames from standard input. # # Usage: glf [directory|-] [regex] # # glf # glf . # glf . ^ # these are equivalent usages. ^ is the fastest # # regex to match any filename. # # glf /var/log maillog # return latest file whose name matches maillog # # find /var/log -name "mail*" | glf - # supply filenames to search on # # standard input # # perldoc perlre For more information about the regular # expression syntax. use strict; use File::Spec (); my $DEBUG = 0; my $directory = shift || '.'; my $file_regex = shift || qr/^/; $directory = File::Spec->rel2abs($directory) unless $directory eq '-'; warn "info: checking directory $directory\n" if $DEBUG; my $latest_mtime; my $latest_file; if ( $directory eq '-' ) { while ( my $file = ) { chomp($file); warn "info: considering file $file\n" if $DEBUG; handle_file($file); } } else { # So that unqualified file paths relative to directory supplied, and # not whatever random directory the CWD inherits. Less expensive than # applying File::Spec->catfile() to each filename. chdir($directory) or die "error: cannot chdir $directory: $!\n"; my $dir_handle; opendir( $dir_handle, "$directory" ) or die "error: cannot open $directory: $!\n"; while ( my $file = readdir($dir_handle) ) { warn "info: considering file $file\n" if $DEBUG; handle_file($file); } } if ( defined $latest_file ) { print $latest_file, $/; exit 0; } else { exit 1; } sub handle_file { my $file = shift; return unless defined $file and length $file > 0; return unless $file =~ m/$file_regex/; return unless -f $file; my $file_mtime = ( stat($file) )[9]; warn "info: file $file mtime $file_mtime\n" if $DEBUG; if ( !defined $latest_mtime or $file_mtime > $latest_mtime ) { $latest_mtime = $file_mtime; $latest_file = $file; } }