2013-05-28 4 views
5

Gibt es eine Möglichkeit, eine Bestellung aus der Liste readdir zu garantieren?Perl Readdir in Reihenfolge

Ich habe den Code:

opendir(my $DIR, $src) or die "Error opening $src"; 

# Loop for each file in the directory 
while (my $file = readdir($DIR)) 
{ 
     print "$file\n"; 
} 

aber es gibt in zufälliger Reihenfolge. Jetzt weiß ich, dass es viele Lösungen über eine schnelle Google-Suche gibt, aber ich kann nicht die genaue Reihenfolge finden, die ich brauche. Grundsätzlich möchte ich, dass die Ordner FIRST oder LAST, und nicht zwischen den Dateien angezeigt werden.

Zum Beispiel gerade jetzt, wenn ich die Ordnerstruktur haben:

folder 
folder 
file1 
file2 
file3 

ich das Ergebnis:

file2 
folder 
folder 
file1 
file3 

Wenn wirklich ich will:

folder 
folder 
file1 
file2 
file3 

Oder:

file1 
file2 
file3 
folder 
folder 

Jeder Weg, dies zu erreichen?

Danke.

+0

eine Art Art verwendet werden soll. –

Antwort

4

Sie durch Ordner zuerst setzen und dann die Sortierung nach Datei/dir Namen sortieren,

# $src pointing to folder open with opendir 
my @sorted_dir = 
    map $_->[0], 
    sort { 
    $a->[1] <=> $b->[1] 
     || 
    $a->[0] cmp $b->[0] 
    } 
    map [ $_, -f "$src/$_" ], 
    readdir($DIR); 

Während ähnlicher Effekt kann erreicht werden durch,

for my $file (sort { -f "$src/$a" <=> -f "$src/$b" } readdir($DIR)) { 
    print "$file\n"; 
} 

es ist langsamer und ineffizienter, da es häufiger Geht zum Dateisystem, ob der Verzeichniseintrag eine einfache Datei ist.

+0

Danke, ich habe auf eine elegantere Lösung gehofft. Ich werde darauf zurückgreifen, wenn alles andere nicht funktioniert :) – Travv92

+0

Aktualisiert mit einfacher aber langsamer Alternative. –

+0

Danke, das ist ein schöner aussehender. Das war auch das Problem mit der anderen Lösung von Simbabque, es fehlte '$ src /' und deshalb funktionierte es nicht! – Travv92

5

Sie könnten eine sort verwenden, um es zu tun, indem Sie auf jeden Eintrag der Liste, die von zurückgegeben wird.

opendir(my $DIR, '.') or die "Error opening "; 

foreach my $file (sort { -d $a <=> -d $b } readdir($DIR)) { 
    print "$file\n"; 
} 

Dies wird Ordner zuletzt geben.

+0

Hallo, wenn ich das tue, bekomme ich 'Verwendung von nicht initialisierten Wert im numerischen Vergleich (<=>)'. – Travv92

+0

Versuchen Sie 'cmp' anstelle von' <=> '. – innaM

+0

Jetzt bekomme ich 'Verwendung von nicht initialisierten Wert im String-Vergleich (cmp)'. Das Entfernen der "-d" von beiden ergibt keine Fehler (aber offensichtlich falsche Ausgabe) .. – Travv92

2

Sie part von List::MoreUtils

#!/usr/bin/env perl 

use strict; 
use warnings; 

use List::MoreUtils 'part'; 

my $dir = shift || '.'; 

opendir my $dh, $dir or die "Cannot open $dir"; 

my ($files, $dirs) = part { -d } sort readdir $dh; 

print "$_\n" for @$files, @$dirs; 

Für eine andere Idee verwenden können, können Sie bei File::Next aussehen.

+0

Danke, obwohl ich das lieber ohne Pakete mache .. – Travv92

+0

Es funktioniert, es ist einfach zu lesen, und Sie haben es fast sicher schon. Aber ... deine Wahl. –

3

foreach (sort readdir $dh) {} funktioniert gut für mich.

Zum Beispiel:

opendir (my $DIR, "$dir") || die "Error while opening $dir: $!\n"; 

foreach my $dirFileName(sort readdir $DIR) 
{ 
     next if $dirFileName eq '.' or $dirFileName eq '..'; 
     print("fileName: $dirFileName ... \n"); 
}