9 Stimmen

Wie kann ich die Dateien in einem Verzeichnis in sortierter Reihenfolge lesen?

Wenn ich ein Verzeichnis in Perl mit opendir , readdir et closedir die readdir Funktion scheint die Dateien nicht in einer bestimmten Reihenfolge zu lesen (soweit ich das beurteilen kann).

Ich lese ein Verzeichnis mit Unterverzeichnissen, die nach Epochenzeitstempel benannt sind:

1224161460
1228324260
1229698140

Ich möchte diese Verzeichnisse in numerischer Reihenfolge einlesen, d.h. die ältesten Verzeichnisse stehen an erster Stelle.

Wenn ich die readdir Die erste Zahl ist 1228324260, die mittlere Zahl. Ich weiß, ich könnte den Inhalt des Verzeichnisses in ein Array packen und das Array sortieren, aber gibt es eine Option, die ich an readdir in sortierter Reihenfolge zu lesen? Oder vielleicht einen eleganteren Weg, dies zu erreichen, als alles in Array zu schieben und das Array zu sortieren? Es gibt wahrscheinlich Module, die dies ebenfalls tun, aber es ist schwierig, Module in unserer Umgebung zu installieren, also würde ich es vorziehen, keine Module zu verwenden, es sei denn, es ist ein eingebautes Modul...

Danke!

EDIT Wie gewünscht, werde ich den von mir verwendeten Code veröffentlichen:

opendir( my $data_dh, $data_dir ) or die "Cannot open $data_dir\n";
while ( my $name = readdir($data_dh) ) {
    next if ( $name eq '.' or $name eq '..' );
    my $full_path = "${data_dir}/${name}";
    next unless ( -d $full_path );
    process_dir($full_path);
}
closedir($data_dh);

15voto

Andrew Barnett Punkte 4826

readdir kann im Array-Kontext aufgerufen werden, also tun Sie dies einfach:

opendir( my $data_dh, $data_dir) or die "Cannot open $data_dir\n";
my @files = sort { $a <=> $b } readdir($data_dh);
while ( my $name = shift @files ) {
...

5voto

Kent Fredric Punkte 55042

Sie können es mit ein bisschen Glob-Magie versuchen, glob scheint sortiert zu funktionieren, also dies:

#  Glob in scalar context iterates the result set internally
while( defined( my $dir = glob($dir . '/*' ) ) ){ 
     print $dir, "\n";
    # $dir is fed ordered and with full names. 
}

o

# Glob in list context returns all results. 
for( glob($dir.'/*' ) ){ 
  print $dir , "\n";
  # also ordered. 
}

sollte funktionieren. Seien Sie nur vorsichtig mit glob, weil dies:

 for(0..20){ 
   printf "%30s|%30s\n", glob($dir.'/*' ), glob($dir.'/*' );
 }

tut etwas halbmagisches und gibt den Inhalt des Verzeichnisses zweimal in jeder Zeile aus, d.h.:

/foo/bar/a  |  /foo/bar/a
/foo/bar/b  |  /foo/bar/b
/foo/bar/c  |  /foo/bar/c
/foo/bar/d  |  /foo/bar/d

5voto

brian d foy Punkte 124323

Werfen Sie einfach eine sort vor jedem Listenoperator, den Sie neu ordnen möchten. Sie brauchen die Ergebnisse auch nicht in einem Array zu speichern. Sie können eine foreach :

opendir my($dh), $dirname or die "Could not open directory [$dirname]: $!";

foreach my $file ( sort { $a <=> $b } readdir $dh )
    {
    ...
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X