当我使用opendir
,readdir
和closedir
读取Perl中的目录时,readdir
函数似乎无法按任何特定顺序读取文件(我可以告诉你。
我正在读取一个目录,该目录包含以epoch timestamp命名的子目录:
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 :(得分: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 ) {
...
答案 1 :(得分: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.
}
应该有效。请小心使用glob,因为:
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
答案 2 :(得分:5)
只需在您要重新排序的任何列表运算符前面放一个sort
。您也不需要将结果存储在数组中。您可以使用foreach
:
opendir my($dh), $dirname or die "Could not open directory [$dirname]: $!";
foreach my $file ( sort { $a <=> $b } readdir $dh )
{
...
}