Amit Saxena wrote:
Hi all,

Hello,

The following perl program, for sorting files in a directory, without using
any OS specific command, ordered by modified timestamp is not working.

Please help.

*Perl Program*

#!perl.exe

use strict;
use warnings;

my $directory_name;
print "This program print the files in ascending order of timestamp.\n";
print "\n";
## print "Enter directory name : ";
##
## $directory_name =<STDIN>;
## chomp $directory_name;

$directory_name = "/tmp/test/";

die "ERROR :<<$directory_name>>  is NOT a directory, $!\n" if ( ! -d
$directory_name );

my @files_in_directory;
opendir ( DIR1, $directory_name ) or die "Unable to open the directory
<<$directory_name>>  : $!\n";
my $filename;
while ( defined ( $filename = readdir ( DIR1 ) ) )

You don't need $filename visible outside the while loop so that is usually written as:

while ( my $filename = readdir DIR1 )

(The defined() is implied with readdir and readline.)


{
         next if ( ( $filename eq "." ) or ( $filename eq ".." ) );

         push ( @files_in_directory, $filename );
}

Since all you are doing is populating the array you could just do it like this:

my @files_in_directory = grep !/\A\.\.?\z/, readdir DIR1;


closedir ( DIR1 );

print "Unsorted listing of files in<$directory_name>  directory are as
follows :-\n";
my $i;
foreach $i ( @files_in_directory )

That is usually written as:

foreach my $i ( @files_in_directory )


{
         print $i . "\n";
         # my ( $atime, $mtime, $ctime );
         #( undef, undef, undef, undef, undef, undef, undef, undef, $atime,
$mtime, $ctime, undef, undef ) = ( stat($i) );
         #print "atime=[$atime],mtime=[$mtime],ctime=[$ctime]\n";
         # print "atime=[" . (stat($i))[8] . "],mtime=[" . (stat($i))[9] .
"],ctime=[" . (stat($i))[10] . "]\n";
}
print "\n";

my @sorted_files_in_directory;
@sorted_files_in_directory = sort { (stat($a))[9]<=>  (stat($b))[9] }

If you read the documentation for readdir you will see where it says:

            If you're planning to filetest the return values out of a
            "readdir", you'd better prepend the directory in question.
            Otherwise, because we didn't "chdir" there, it would have
            been testing the wrong file.

So with the directory prepended you would have:

my @sorted_files_in_directory = sort { (stat "$directory_name/$a" )[ 9 ] <=> ( stat "$directory_name/$b" )[ 9 ] } @files_in_directory;

Although that means that you are stat-ing each file more than once. A more efficient way to do that is to use a Schwartzian Transform which will only stat each file once:

my @sorted_files_in_directory =
    map $_->[ 1 ],
    sort { $a->[ 0 ] <=> $b->[ 0 ] }
    map { stat "$directory_name/$_", $_ }
    @files_in_directory;


@files_in_directory;

print "Sorted listing of files in<$directory_name>  directory are as follows
:-\n";
my $j;
foreach $j ( @files_in_directory )
{
         print $j . "\n";
}
print "\n";

Or just:

print map( "$_\n", @files_in_directory ), "\n";




John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction.                   -- Albert Einstein

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to