2009-01-12 176 views
8

当我使用Perl以opendir,readdirclosedir读取一个目录时,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); 
+0

我用perl 5.8.2在AIX中,如果它的确与众不同 – BrianH 2009-01-12 17:23:06

+0

我知道这是一个简单的脚本,但是你可以发布您的代码,所以我们不必重现它? – 2009-01-12 17:24:52

+1

process_dir之前的&符号不是必需的,并且在某些情况下可能有害。我会建议你删除它。 – 2009-01-12 19:13:35

回答

13

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

你可以尝试一下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 
5

只要将sort放在您想要重新排序的任何列表操作符的前面。您不需要将结果存储在数组中。您可以使用foreach

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

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