Perl - sort filenames by order based on the filemask YYY-MM-DD that is in the filename

StackOverflow https://stackoverflow.com/questions/22161418

  •  19-10-2022
  •  | 
  •  

Question

Need some help, not grasping a solution here on what method I should use.

I need to scan a directory and obtain the filenames by order of

1.YYYY-MM-DD, YYYY-MM-DD is part of the filename.

2. Machinename which is at the start of the filename to the left of the first "."

For example

Machine1.output.log.2014-02-26
Machine2.output.log.2014-02-27
Machine2.output.log.2014-02-26
Machine2.output.log.2014-02-27
Machine3.output.log.2014-02-26

So that it outputs in an array as follows

Machine1.output.log.2014-02-26
Machine2.output.log.2014-02-26
Machine3.output.log.2014-02-26
Machine1.output.log.2014-02-27
Machine2.output.log.2014-02-27

Thanks,

No correct solution

OTHER TIPS

Often, temporarily turning your strings into a hash or array for sorting purposes, and then turning them back into the original strings is the most maintainable way.

my @filenames = qw/
    Machine1.output.log.2014-02-26
    Machine2.output.log.2014-02-27
    Machine2.output.log.2014-02-26
    Machine2.output.log.2014-02-27
    Machine3.output.log.2014-02-26
/;

@filenames =
    map $_->{'orig_string'},
    sort {
        $a->{'date'} cmp $b->{'date'} || $a->{'machine_name'} cmp $b->{'machine_name'}
    }
    map {
        my %attributes;
        @attributes{ qw/orig_string machine_name date/ } = /\A(([^.]+)\..*\.([^.]+))\z/;
        %attributes ? \%attributes : ()
    } @filenames;

You can define your own sort like so ...

my @files = (
                "Abc1.xxx.log.2014-02-26"
        ,       "Abc1.xxx.log.2014-02-27"
        ,       "Abc2.xxx.log.2014-02-26"
        ,       "Abc2.xxx.log.2014-02-27"
        ,       "Abc3.xxx.log.2014-02-26"
);


foreach my $i ( @files ) { print "$i\n"; }

sub bydate {
        (split /\./, $a)[3] cmp (split /\./, $b)[3];
}

print "sort it\n";
foreach my $i ( sort bydate @files ) { print "$i\n"; }

You can take your pattern 'YYYY-MM-DD' and match it to what you need.

#!/usr/bin/perl
use strict;

opendir (DIRFILES, ".") || die "can not open data file \n";
my @maplist = readdir(DIRFILES);
closedir(MAPS);
my %somehash;

foreach my $tmp (@maplist) {
    next if $tmp =~ /^.{1,2}$/;
    next if $tmp =~ /test/;
   $tmp =~ /(\d{4})-(\d{2})-(\d{2})/;
   $somehash{$tmp} = $1 . $2 . $3; # keep the original file name
                                   # allows for duplicate dates 


}

foreach my $tmp (keys %somehash) {
    print "-->",  $tmp, " --> " , $somehash{$tmp},"\n";
}
my @list= sort { $somehash{$a} <=> $somehash{$b} } keys(%somehash);

foreach my $tmp (@list) {
    print $tmp, "\n";
}

Works, tested it with touch files.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top