Как я могу прочитать файлы в каталоге в отсортированном порядке?
Когда я читаю каталог в Perl с opendir
, readdir
, а также closedir
, readdir
Кажется, функция не читает файлы в каком-то определенном порядке (что я могу сказать).
Я читаю каталог, в котором есть подкаталоги, названные меткой времени эпохи:
1224161460
1228324260
1229698140
Я хочу читать в этих каталогах в числовом порядке, который ставит самые старые каталоги на первое место.
Когда я использую readdir
, первый, который он читает, является 1228324260, который является средним. Я знаю, что могу поместить содержимое каталога в массив и отсортировать массив, но есть ли опция, которую я могу передать readdir
читать в отсортированном порядке? Или, может быть, более элегантный способ сделать это, чем помещать все в массив и сортировать массив? Вероятно, существуют модули для этого, но установить модули в нашей среде сложно, поэтому, если это не встроенный модуль, я бы предпочел не использовать модули...
Спасибо!
РЕДАКТИРОВАТЬ В соответствии с просьбой, я публикую код, который я использую:
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 ответа
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 ) {
...
Просто брось sort
перед любым оператором списка, который вы хотите изменить порядок. Вам также не нужно хранить результаты в массиве. Вы можете использовать foreach
:
opendir my($dh), $dirname or die "Could not open directory [$dirname]: $!";
foreach my $file ( sort { $a <=> $b } readdir $dh )
{
...
}
Вы можете попробовать это с небольшим количеством магии 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.
}
или же
# 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