Retrieving a List of Files Sorted by Modified by Perl

I am trying to get a list of files sorted by date modified. I changed the sample program from the Sort directory and the list of files based on the date and time and tried to run it.

sub get_sorted_files { my $path = shift; opendir my($dir), $path or die "can't opendir $path: $!"; my %hash = map {$_ => (stat($_))[9]} map { "$dir$_" } grep { m/.*/i } readdir $dir; closedir $dir; return %hash; } my %files = get_sorted_files("."); foreach my $keys (sort{$files{$a} <=> $files{$b}} keys %files) { print "$keys\t", scalar localtime($files{$keys}), "\n"; } 

I run this on my 32-bit Windows XP machine using Strawberry Perl version 5.12.1.0.

List of directories in Windows:

alt text

Output:

alt text

The way out doesn't make much sense to me. What happens to this piece of code, and how exactly does the foreach sort the list of files?

+4
source share
4 answers

In get_sorted_files , $dir is the globe, not the directory name. Did you mean $path ?

 my %hash = map {$_ => (stat($_))[9]} map { "$path/$_" } # $path, not $dir grep { m/.*/i } readdir $dir; 
+4
source

There are at least 2 problems in this code. Here is the best version:

 use strict; use warnings; # I bet you weren't using this, because it produced a lot sub get_sorted_files { my $path = shift; opendir my($dir), $path or die "can't opendir $path: $!"; my %hash = map {$_ => (stat($_))[9] || undef} # avoid empty list map { "$path$_" } readdir $dir; closedir $dir; return %hash; } my %files = get_sorted_files("./"); foreach my $key (sort{$files{$a} <=> $files{$b}} keys %files) { print "$key\t", scalar localtime($files{$key}), "\n"; } 

First you renamed $dir in the source code to $path , but you did not change it in the map line. Your $dir is a directory descriptor; that where GLOB (0x ...) comes from.

Secondly, all modification dates are read "Wed December 31 16:00:00 1969" because you passed the wrong path to stat . (stat($_))[9] returned an empty list (because you were looking for a file such as GLOB(0x3f9b38)status.txt instead of the correct path name), and so the hash was actually completed containing the file names as both keys and values. The first file name was the key, the second was its value, the third was the next key, and so on. localtime converts the file name to a number (with 0), and then converts the era 0 time (Jan-1-1970 0:00:00 UTC) to your time zone.

Third, it expects $path end with a directory separator, and you pass "." . You will need to go through "./" or, even better, fix it so that the function adds a separator if necessary.

Fourth, grep did nothing else and should be removed. (In the source code, he selected only certain file names, but you changed the template to suit everything.)

How it sorts file names: get_sorted_files returns a list of path names and modification times that you store in the %files hash. keys %files returns a list of keys (file names) and sorts them by numerically comparing the associated value (modification time).

+7
source

Use Perl sort . It’s faster and you get what you want without a hash.

File size, then file age:

@s = sort {-s $ a <=> -s $ b || -M $ b <=> -M $ a} @a;

Knowing above, we can say something like below:

 sub get_sorted_files { my $path = shift; opendir my($dirh), $path or die "can't opendir $path: $!"; my @flist = sort { -M $a <=> -M $b } # Sort by modification time map { "$path/$_" } # We need full paths for sorting readdir $dirh; closedir $dirh; return @flist; } 
+6
source

For really large directories, you may find that Perl is significantly slower than using your own sorting tools. For example, on my machine in a huge directory (341 thousand files) it takes about 1.5 minutes:

 my $mostrecent = `/bin/ls --full-time -lta $dir | head -1 2>/dev/null`; 

But the code in the solution above (using opendir and sort -M ) lasts from 30 to 45 seconds. Not only is this much faster, you can also avoid Perl storing the entire array in memory, which can be a win in itself.

Please note that the above applies to a fairly high-level Linux blade system, so YMMV on PC / OS ...

0
source

Source: https://habr.com/ru/post/1334985/


All Articles