Reputation: 215
I have gone through a bunch of questions to find the best way to get the names of the files from a directory. However, I have a peculiar scenario and need some help.
The files in my direcotry are as follows
-rw-rw-r-- 1 root 55000 53916 Apr 12 2013 Update_2013-04-12_02-17-55.txt
-rw-rw-r-- 1 root 55000 53916 Apr 12 2013 UpdateCIMS_2013-04-12_03-20-30.txt
-rw-rw-r-- 1 root 55000 53763 Apr 15 2013 UpdateCIMSFlag_2013-04-15_05-47-41.txt
-rw-rw-r-- 1 root 55000 91981 Apr 23 2013 UserManagementService_2013-04-23_03-55-52.txt
-rw-rw-r-- 1 root 55000 92076 Apr 23 2013 UserManagementService_2013-04-23_04-34-42.txt
-rw-rw-r-- 1 root 55000 92086 Apr 23 2013 UserManagementService_2013-04-23_23-55-10.txt
-rw-rw-r-- 1 root 55000 91971 Apr 24 2013 UserManagementService_2013-04-24_02-23-20.txt
-rw-rw-r-- 1 root 55000 59441 Apr 24 2013 SecuredService_2013-04-24_02-29-08.txt
-rw-rw-r-- 1 root 55000 42240 May 20 2013 UpdateCIMSFlag_2013-05-20_04-24-19.txt
-rw-rw-r-- 1 root 55000 40547 May 20 2013 UpdateCIMSFlag_2013-05-20_05-31-29.txt
-rw-rw-r-- 1 root 55000 42238 May 20 2013 UpdateCIMSFlag_2013-05-20_05-43-54.txt
-rw-rw-r-- 1 root 55000 59493 May 21 2013 SecuredService_2013-05-21_04-25-32.txt
-rw-rw-r-- 1 root 55000 88374 May 21 2013 RegistrationService_2013-05-21_23-55-33.txt
-rw-rw-r-- 1 root 55000 88426 May 22 2013 RegistrationService_2013-05-22_00-20-04.txt
-rw-rw-r-- 1 root 55000 60014 Jul 31 04:16 SecuredService_2013-07-31_04-16-56.txt
-rw-rw-r-- 1 root 55000 91636 Sep 2 06:11 AdminServices_2013-09-02_06-11-17.txt
-rw-rw-r-- 1 root 55000 91649 Sep 3 05:37 AdminServices_2013-09-03_05-37-54.txt
-rw-rw-r-- 1 root 55000 133629 Sep 3 05:43 UserManagementService2_2013-09-03_05-43-56.txt
-rw-rw-r-- 1 root 55000 556 Sep 9 08:26 Test_2013-09-09_08-26-23.txt
-rw-rw-r-- 1 root 55000 556 Sep 9 08:37 Test_2013-09-09_08-37-20.txt
-rw-rw-r-- 1 root 55000 133708 Sep 13 02:28 UserManagementService2_2013-09-13_02-28-49.txt
-rw-rw-r-- 1 root 55000 60107 Sep 13 02:30 SecuredService_2013-09-13_02-30-43.txt
-rw-rw-r-- 1 root 55000 133743 Sep 13 04:44 UserManagementService2_2013-09-13_04-44-29.txt
-rw-rw-r-- 1 root 55000 100886 Sep 16 04:27 AdminServices_2013-09-16_04-27-33.txt
-rw-rw-r-- 1 root 55000 556 Sep 20 06:40 Test_2013-09-20_06-40-16.txt
-rw-rw-r-- 1 root 55000 110236 Nov 25 02:35 AdminServices_2013-11-25_02-35-37.txt
-rw-rw-r-- 1 root 55000 142357 Dec 18 03:13 UserManagementService2_2013-12-18_03-13-20.txt
As you can see, i have similar files with different timestamps and different files. So i need the file names which are similar excluding the timestamp and the latest file from them. I want my end result to display the latest, unique filenames with the timestamp.
I am trying opendir but am not seeing any result.
#!/usr/bin/perl
use File::stat;
my $DIR = "/home/DIR";
opendir(my $DH, $DIR) or die "Error opening the dir";
my %files = map { $_ => (stat("$DIR/$_"))[9] } grep(! /^\.\.?$/, readdir($DH));
closedir($DH);
my @sorted_files = sort { $files{$b} <=> $files{$a} } (keys %files);
print $_;
Please help. The output I am expecting is
AdminServices_2013-11-25_02-35-37.txt
UserManagementService2_2013-12-18_03-13-20.txt
SecuredService_2013-09-13_02-30-43.txt
RegistrationService_2013-05-22_00-20-04.txt
etc...
Upvotes: 2
Views: 175
Reputation: 50637
#!/usr/bin/perl
my $DIR = "/home/DIR";
opendir(my $DH, $DIR) or die $!;
my %files;
while (my $f = readdir($DH)) {
next if $f =~ /^\.\.?$/;
my ($key, $t) = split /_/, $f, 2;
# @{ $files{$key} }{ "t","f" } = ($t, $f)
# if !$files{$key} or $files{$key}{t} lt $t;
my $h = $files{$key} ||= {};
if (! %$h or $h->{t} lt $t) {
$h->{t} = $t;
$h->{f} = $f;
}
}
print "$files{$_}{f}\n" for sort keys %files;
Upvotes: 0
Reputation: 5069
You could use glob:
my $filespec = "/tmp/test*";
my %files;
while (my $file = glob("$filespec") ){
next if $file eq '.' or $file eq '..';
next if ! -f $file;
my $datestamp = (stat($file))[9];
#remove timestamp
my $filename = $file;
$filename =~ s!_\d{4}-\d{2}-\d{2}_\d{4}-\d{4}-\d{4}\.\W{3}\z!!is;
if (! exists $files{$filename} || $files{$filename}<$datestamp){
$files{$filename} = $datestamp;
$files{$filename} = $datestamp;
}
}
foreach my $key (sort { $files{$b} <=> $files{$a} } (keys %files)){
print "$key\t$files{$key}\n";
}
Upvotes: 0
Reputation: 2906
For a start, opendir
isn't the problem. You aren't using the print statement correctly.
foreach(@sorted_files)
{ print $_ . "\n"; }
That outputs the file names. This is only a start to get you some output. I didn't finish the problem.
Upvotes: 1