如何在Perl中获取嵌套目录内容

时间:2010-09-06 06:57:41

标签: perl file directory

我正在尝试编写一个处理某些文件的脚本。数据的组织方式如下:有一个文件夹(我们称之为X),我的脚本将被放置在该文件夹中。在同一个文件夹中有一个名为“data”的子文件夹。这包含几个具有各种名称的子文件夹,每个子文件夹包含许多文件(没有其他子文件夹,只有文件)。我需要处理子文件夹中的所有文件(更具体地说,在每个文件上运行一个函数),然后合并子文件夹中所有文件的结果,因此对于每个文件夹都有一个结果(无论它包含多少文件)。

问题是,我无法访问文件,因此我可以在它们上运行我的功能。我现在拥有的是:

$dirname = "data";

opendir ( DIR, $dirname ) || die "Error in opening dir $dirname\n";

while( ($dirname2 = readdir(DIR)) ) 
{
    next if $dirname2 eq ".";
    next if $dirname2 eq "..";

    opendir ( DIR2, $dirname2 ) || die "Error in opening dir $dirname2\n";

    while( ($file = readdir(DIR2)) ) 
    {
        next if $file eq ".";
        next if $file eq "..";

        print( "file:$file\n" );
    }

    closedir(DIR2);

}
closedir(DIR);

它始终失败并显示消息“打开dir alex时出错”。 'alex'恰好是数据目录中的第一个目录。我的问题是 - 问题出在哪里?这甚至是如何实现我想要做的正确方法吗?如果数据文件夹中也有文件,我也担心这会失败,因为我无法用opendir打开它,或者我可以吗?

PS:对于那可怕的Perl代码感到抱歉 - 我还在努力学习这门语言。

谢谢, 彼得

4 个答案:

答案 0 :(得分:2)

您可以使用File::Find来查找文件嵌套目录

答案 1 :(得分:2)

您可以尝试File::Path - 创建或删除目录树

当我运行你的程序时,我认为你必须在打开目录时指定完整路径,即。,

opendir ( DIR2, $dirname.\\.$dirname2 ) || die "Error in opening dir $dirname2\n"; #running code on windows

它会起作用,试一试。

答案 2 :(得分:2)

您确定内部文件夹只存在文件夹吗?添加其他支票:

next if !(-d $dirname2);

答案 3 :(得分:2)

以下是问题中发布内容的略微清理版本。

use strict;
use warnings;
use autodie;
use File::Spec::Functions qw'catdir catfile';

my $dirname = "data";

{
    opendir my $dir_h, $dirname;

    while( my $dirname2 = readdir($dir_h) ){
        next if $dirname2 eq ".";
        next if $dirname2 eq "..";

        $dirname2 = catdir( $dirname, $dirname2 );
        next unless -d $dirname2;
        opendir my $dir_h2, $dirname2;

        while( my $file = readdir($dir_h2) ) 
        {
            next if $file eq ".";
            next if $file eq "..";

            $file = catfile($dirname2,$file);
            if( -f $file ){
              print( "file:$file\n" );
            }
        }
        # $dir_h2 automatically closes here
    }
    # $dir_h automatically closes here
}

如果你要在早于5.12.0的Perl版本上运行它,你应该用defined()包装while循环。

    while( my $dirname2 = readdir($dir_h) ){
    while( defined( my $dirname2 = readdir($dir_h) ) ){