Reputation: 59
How can I read the content of the last modified file in a directory in perl
I have a tool for received sms and I want to give out the content of the last modified file , which is stored in gammu/inbox directory , with a perl script
for example: the script checked if a new sms in folder(gammu/inbox), are they, then give out the content from the last sms.
Upvotes: 0
Views: 534
Reputation: 126722
Sort the directory according to the age of each file, using the -M
file test operator. The most recently modified file will then be the first in the list
This program shows the principle. It finds the latest file in the current working directory, prints its name and opens it for input
If you want to do this for a directory other that the cwd then it is probably easiest just to chdir
to it and use this code than to try to opendir
a specific directory, as then you will have to build the full path to each file before you can use -M
use strict;
use warnings 'all';
use feature 'say';
my $newest_file = do {
opendir my $dh, '.' or die $!;
my @by_age = sort { -M $a <=> -M $b } grep -f, readdir $dh;
$by_age[0];
};
say $newest_file;
open my $fh, '<', $newest_file or die qq{Unable to open "$newest_file" for input: $!};
If you are working with a sizeable directory then this may take some time as a stat
operation is quite slow. You can improve this a lot by using a Schwartzian Transform so that stat
is called only once for each file
my $newest_file = do {
opendir my $dh, '.' or die $!;
my @by_age = map $_->[0],
sort { $a->[1] <=> $b->[1] }
map [ $_, -M ], readdir $dh;
$by_age[0];
};
If you want something really fast, then just do a single pass of the files, keeping track of the newest found so far. Like this
my $newest_file = do {
opendir my $dh, '.' or die $!;
my ($best_file, $best_age);
while ( readdir $dh ) {
next unless -f;
my $age = -M _;
unless ( defined $best_age and $best_age < $age ) {
$best_age = $age;
$best_file = $_;
}
}
$best_file;
};
Upvotes: 3
Reputation: 7
You need to get an ordered list of file with
use File::DirList;
my @list = File::DirList::list('your_directory', 'M');
Than the first element of list is what you are looking for.
You can read more about the library here File::DirList
Upvotes: 0