Ваш путь - «правильный», если вам нужен отсортированный список (и не только первый, см. Ответ Брайана за это). Если вы не хотите писать этот код самостоятельно, используйте this
use File::DirList;
my @list = File::DirList::list('.', 'M');
Лично я бы не стал использовать метод ls -t
- он включает в себя разветвление другой программы, и она не переносима. Вряд ли то, что я бы назвал "элегантным"!
Что касается решения, написанного от Rjray, я бы немного его изменил:
opendir(my $DH, $DIR) or die "Error opening $DIR: $!";
my @files = map { [ stat "$DIR/$_", $_ ] } grep(! /^\.\.?$/, readdir($DH));
closedir($DH);
sub rev_by_date { $b->[9] <=> $a->[9] }
my @sorted_files = sort rev_by_date @files;
После этого @sorted_files
содержит отсортированный список, где 0-й элемент является самым новым файлом, а каждый элемент сам содержит ссылку на результаты stat
с именем самого файла в последнем элементе:
my @newest = @{$sorted_files[0]};
my $name = pop(@newest);
Преимущество этого в том, что при желании легче изменить метод сортировки.
РЕДАКТИРОВАТЬ: вот более легкая для чтения (но более длинная) версия сканирования каталогов, которая также обеспечивает добавление в список только простых файлов:
my @files;
opendir(my $DH, $DIR) or die "Error opening $DIR: $!";
while (defined (my $file = readdir($DH))) {
my $path = $DIR . '/' . $file;
next unless (-f $path); # ignore non-files - automatically does . and ..
push(@files, [ stat(_), $path ]); # re-uses the stat results from '-f'
}
closedir($DH);
Примечание: проверка defined()
на результат readdir()
вызван тем, что файл с именем '0' приведет к сбою цикла, если вы будете проверять только if (my $file = readdir($DH))