Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Getting latest modified file in a directory

by ovedpo15 (Pilgrim)
on Jan 10, 2022 at 16:05 UTC ( [id://11140328]=perlquestion: print w/replies, xml ) Need Help??

ovedpo15 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks!
I want to build a subroutine which returns the latest modified file in an array of files (could be regular file, link or directory).
The area is given in $base_dir variable and the filenames list hash ref is given in $filenames_href (The keys are the number and the values are just "1").
The initial code:
sub test { my ($base_dir,$filenames_href) = @_; foreach my $filename (keys(%{$filenames_href})) { my $file_path = catfile($base_dir,$filename); # Could be file, + dir, link, ... # TODO: Check if the $file_path is the latest I seen ? } return $latest_modified_file; }
For example:
ls -la . -rw-r----- 1 user group 33659 Nov 3 14:49 a drwxr-x--- 3 user group 4096 May 3 2021 b drwxr-x--- 3 user group 4096 Dec 8 16:18 c -rwxr-x--x 1 user group 67 Apr 5 2021 e drwxr-x--- 4 user group 4096 Nov 1 15:29 f -rw-r----- 1 user group 798 Nov 15 17:00 g
In that case the sub should return c because it was modified latest. Is there a standard way to do it?

Replies are listed 'Best First'.
Re: Getting latest modified file in a directory
by hippo (Bishop) on Jan 10, 2022 at 16:24 UTC
    Is there a standard way to do it?

    No but there are many ways to do it. Here is one:

    #!/usr/bin/env perl use strict; use warnings; use List::Util 'reduce'; use Path::Tiny 'path'; my @files = qw/a b c/; my $dir = '/tmp/'; print newest($dir, @files) . "\n"; sub newest { my $dir = shift; my $newest = reduce { $a->stat->mtime > $b->stat->mtime ? $a : $b +} map { path "$dir/$_" } @_; return "$newest"; }

    I've passed the files as an array since that is much more useful (in a generic sense) than your hashref. Feel free to modify for your own purposes, of course. If your list of files is (or might be) very long then consider a transform to avoid excessive stat calls.


    🦛

Re: Getting latest modified file in a directory
by Fletch (Bishop) on Jan 10, 2022 at 18:29 UTC

    Variation on the above theme for an instance if you actually wanted all of the files ordered newest to oldest and not just the newest:

    my @files_by_age = map { $_->[1] } sort { $b->[0]<=>$a->[0] } map { [ $_->stat->mtime, $_ ] } grep { $_->is_file } path( q{/tmp} )->children();

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: Getting latest modified file in a directory
by tybalt89 (Monsignor) on Jan 10, 2022 at 21:08 UTC
    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11140328 use warnings; use List::AllUtils qw( max_by ); my $latest = max_by { (stat)[9] } glob 'tmp*'; # or your file list print "latest = $latest\n";
Re: Getting latest modified file in a directory -- oneliner
by Discipulus (Canon) on Jan 11, 2022 at 09:34 UTC
    perl -E "say+(sort{(stat$a)[9]<=>(stat$b)[9]}grep{-f}glob'*')[-1]"

    L*

    PS sorry.. the latest is indexed -1 not 0 which is the oldest

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11140328]
Approved by LanX
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2024-03-28 23:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found