2013-05-28 56 views
5

有什麼方法可以保證readdir返回列表中的訂單嗎?Perl readdir以訂購

我的代碼:

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

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

但它以隨機順序返回。現在我知道有很多解決方案通過快速Google搜索,但我找不到我需要的確切順序。 基本上我希望文件夾出現在FIRST或LAST中,而不是在文件之間。

例如,現在如果我有文件夾結構:

folder 
folder 
file1 
file2 
file3 

我得到的結果是:

file2 
folder 
folder 
file1 
file3 

當我真的想:

folder 
folder 
file1 
file2 
file3 

或者:

file1 
file2 
file3 
folder 
folder 

任何方式來實現這一目標?

謝謝。

+0

應使用某種形式的。 –

回答

4

您可以通過將文件夾,然後再通過文件/目錄名排序排序,

# $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); 

雖然類似的效果可以實現,

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

它的速度較慢,效率低下,因爲它更多的時候如果目錄條目是普通文件,則進入文件系統檢查。

+0

謝謝,我希望能有更優雅的解決方案。如果一切都失敗,我會回到這裏:) – Travv92

+0

更新更簡單但速度更慢的替代方案。 –

+0

謝謝,這是一個更好看。這也是simbabque提供的其他解決方案的問題,它缺少'$ src /',這就是爲什麼它不工作! – Travv92

5

您可以使用sort來做到這一點,通過查看readdir返回列表的每個條目。

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

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

這會給文件夾留下最後。

+0

嗨,當我這樣做時,我得到'在數值比較中使用未初始化值(<=>)'。 – Travv92

+0

嘗試'cmp'而不是'<=>'。 – innaM

+0

現在我得到'在字符串比較(cmp)'中使用未初始化的值'。從兩者中刪除'-d'都不會產生錯誤(但顯然輸出錯誤)。 – Travv92

2

您可以使用partList::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; 

對於另一個想法,你可能看File::Next

+0

謝謝,雖然我更喜歡做這個沒有包裹。 – Travv92

+0

它的作品,它的易於閱讀,你幾乎可以肯定它已經。但是......你的選擇。 –

3

foreach (sort readdir $dh) {}適合我。

例如:

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"); 
}