如何以排序顺序读取目录中的文件?
问题描述:
当我使用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);
答
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) {
...
答
你可以尝试一下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.
}
应该工作。只是要小心有水珠,因为这:
for(0..20){
printf "%30s|%30s\n", glob($dir.'/*'), glob($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
答
只要将sort
放在您想要重新排序的任何列表操作符的前面。您不需要将结果存储在数组中。您可以使用foreach
:
opendir my($dh), $dirname or die "Could not open directory [$dirname]: $!";
foreach my $file (sort { $a <=> $b } readdir $dh)
{
...
}
我用perl 5.8.2在AIX中,如果它的确与众不同 – BrianH 2009-01-12 17:23:06
我知道这是一个简单的脚本,但是你可以发布您的代码,所以我们不必重现它? – 2009-01-12 17:24:52
process_dir之前的&符号不是必需的,并且在某些情况下可能有害。我会建议你删除它。 – 2009-01-12 19:13:35