Как я могу прочитать файлы в каталоге в отсортированном порядке? - PullRequest
8 голосов
/ 12 января 2009

Когда я читаю каталог в Perl с opendir, readdir и closedir, функция readdir, похоже, не читает файлы в каком-то определенном порядке (что я могу сказать).

Я читаю каталог, в котором есть подкаталоги, названные меткой времени эпохи:

1224161460
1228324260
1229698140

Я хочу читать в этих каталогах по порядку номеров, чтобы на первом месте были самые старые каталоги.

Когда я использую readdir, первое, что он читает, это 1228324260, то есть среднее. Я знаю, что могу поместить содержимое каталога в массив и отсортировать массив, но есть ли опция, которую я могу передать readdir для чтения в отсортированном порядке? Или, может быть, более элегантный способ сделать это, чем помещать все в массив и сортировать массив? Вероятно, существуют модули для этого, но сложно установить модули в нашей среде, поэтому, если это не встроенный модуль, я бы предпочел не использовать модули ...

Спасибо!

EDIT По запросу я публикую код, который я использую:

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 ]

13 голосов
/ 12 января 2009

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 ) {
...
5 голосов
/ 12 января 2009

Просто добавьте sort перед любым оператором списка, который вы хотите изменить. Вам также не нужно хранить результаты в массиве. Вы можете использовать foreach:

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

foreach my $file ( sort { $a <=> $b } readdir $dh )
    {
    ...
    }
5 голосов
/ 12 января 2009

Вы можете попробовать это с небольшим количеством магии 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. 
}

или

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

должно работать. Просто будьте осторожны с glob, потому что это:

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

делает что-то полу-магическое и печатает содержимое dir дважды в каждой строке. т.е.:

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