如何按排序順序讀取目錄中的文件?

[英]How can I read the files in a directory in sorted order?


When I read a directory in Perl with opendir, readdir, and closedir, the readdir function doesn't seem to read the files in any specific order (that I can tell).

當我使用opendir,readdir和closedir讀取Perl中的目錄時,readdir函數似乎沒有按任何特定順序讀取文件(我可以告訴)。

I am reading a directory that has subdirectories named by epoch timestamp:

我正在讀一個目錄,其中包含以epoch timestamp命名的子目錄:

1224161460
1228324260
1229698140

I want to read in these directories in numerical order, which would put the oldest directories first.

我想以數字順序讀取這些目錄,這將把最舊的目錄放在第一位。

When I use readdir, the first one it reads is 1228324260, which is the middle one. I know I could put the directory contents in an array and sort the array, but is there an option I can pass to readdir to read in sorted order? Or maybe a more elegant way of accomplishing this than pushing everything into array and sorting the array? There are probably modules out there to do this too, but it is difficult to get modules installed in our environment, so unless it is a built-in module I'd prefer to not use modules...

當我使用readdir時,它讀取的第一個是1228324260,這是中間的。我知道我可以將目錄內容放在一個數組中並對數組進行排序,但是有一個選項可以傳遞給readdir以按排序順序讀取嗎?或者可能是一種更優雅的方法來實現這一點,而不是將所有東西都推入數組並對數組進可能還有模塊可以做到這一點,但很難在我們的環境中安裝模塊,所以除非它是內置模塊,否則我寧願不使用模塊......

Thanks!

EDIT As requested, I am posting the code that I am using:

編輯根據要求,我發布了我正在使用的代碼:

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

3 个解决方案

#1


readdir can be called in array context, so just do this:

readdir可以在數組上下文中調用,所以只需這樣做:

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 ) {
...

#2


You can try it with a bit of Glob magic, glob appears to function in a sorted manner, so this:

你可以嘗試使用一些Glob魔法,glob似乎以排序的方式運行,所以這個:

#  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. 
}

or

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

should work. Just be careful with glob, because this:

應該管用。小心使用glob,因為:

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

does something semi-magical, and prints the dir contents twice on each line. ie:

做一些半神奇的事情,並在每一行打印兩次目錄內容。即:

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

#3


Just throw a sort in front of any list operator that you want to re-order. You don't need to store the results in an array either. You can use a foreach:

只需在要重新排序的任何列表運算符前面進行排序。您也不需要將結果存儲在數組中。你可以使用foreach:

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

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

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2009/01/12/cd2a578c8cb69df1cf3c9baecf9a26b7.html



 
  © 2014-2022 ITdaan.com 联系我们: