Sorting dates in Perl

I have a directory of backup files.

named like this:

ldap.data.04-06-2012.tar
ldap.data.03-06-2012.tar
ldap.data.02-06-2012.tar
ldap.data.01-06-2012.tar
ldap.data.31-05-2012.tar
ldap.data.30-05-2012.tar
ldap.data.29-05-2012.tar
ldap.data.28-05-2012.tar
ldap.data.27-05-2012.tar
ldap.data.26-05-2012.tar
ldap.data.25-05-2012.tar
ldap.data.24-05-2012.tar
ldap.data.23-05-2012.tar
ldap.data.22-05-2012.tar
ldap.data.21-05-2012.tar
ldap.data.20-05-2012.tar
ldap.data.19-05-2012.tar
ldap.data.18-05-2012.tar

I have some perl that read this list of file names like this:

opendir(DIR, "/LDAP_backup");
@FILES= readdir(DIR); 

What I get is the list of files in a almost random order.
what I would like is in date order.

I am not a perl programmer, I have been given some code to "fix"

any thoughts?

Can you try like..

printf '%s\n' *.tar | sort -t_ -k3,4

I was thinking more of using the bulit in sort and just adding my own code.
a bit like the solution given here: sort() array of strings in perl

match on year, then month, then day.
compare each as numbers.

I just don't know how to write that in code.

opendir DIR, "/LDAP_backup";
@files = grep { $_ !~ /^[.]{1,2}$/ } readdir DIR;
closedir DIR;

for (@files) {
    @y = split /[.-]/;
    $x{"$y[4]$y[3]$y[2]"} = $_;
}

for (sort keys %x) {
    print "$x{$_}\n";
}
1 Like

Try this code.

#!/usr/bin/perl

use strict;
use warnings;

#---------------------
# Variable definition
#---------------------
my @temp_fl;
my @sort_fl;
my @frst_str;
my @lst_str;

#---------------------
# Input Path definition
#---------------------
my $fl = "C:\\Users\\easkazi\\Desktop\\file.txt";

open (R, $fl) or die ("Cannot open file $fl");
while (<R>){
    chomp;
    my ($k, $l, $m, $n, $o, $p) = split (/(\w+\.\w+\.)(\d\d)-(\d\d)-(\d+)(\.\w+)/,$_);
    push @temp_fl, "$o$n$m";
    push @frst_str, "$l";
    push @lst_str, "$p";  
   
} 

close ($fl);

@sort_fl = sort {$a <=> $b} @temp_fl;

foreach my $rst_fl(@sort_fl){
   chomp($rst_fl);
   my @rslt = split (/(\d\d\d\d)(\d\d)(\d\d)/,$rst_fl);
   print "$frst_str[0]$rslt[3]-$rslt[2]-$rslt[1]$lst_str[0]\n";    
}

###RESULT DATA#######
ldap.data.18-05-2012.tar
ldap.data.19-05-2012.tar
ldap.data.20-05-2012.tar
ldap.data.21-05-2012.tar
ldap.data.22-05-2012.tar
ldap.data.23-05-2012.tar
ldap.data.24-05-2012.tar
ldap.data.25-05-2012.tar
ldap.data.26-05-2012.tar
ldap.data.27-05-2012.tar
ldap.data.28-05-2012.tar
ldap.data.29-05-2012.tar
ldap.data.30-05-2012.tar
ldap.data.31-05-2012.tar
ldap.data.01-06-2012.tar
ldap.data.02-06-2012.tar
ldap.data.03-06-2012.tar
ldap.data.04-06-2012.tar
ldap.data.24-06-2012.tar

ok .. i might be wrong but this looks like 1 file created everyday ? if yes then read on ..

if files are created according to dates then you can use "ls -lrt" and that will sort the file for you according to creation date!

its not good to depend upon external program but "ls" is pretty basic command and usage remains same on almost all the variants of *NIX...

# latest at bottom 
chomp ( @Files = `ls -1rt <DIR>` ) ;

# latest at top
chomp ( @Files = `ls -1t <DIR>` ) ;

works like magic.

thanks.