我有一个文件夹,里面有很多子文件夹。在这些子文件夹中,我有许多.html文件要读取。我写了以下代码来做到这一点。它打开父文件夹和第一个子文件夹,它只打印一个.html文件。它显示错误:
NO SUCH FILE OR DIRECTORY
我不想改变整个代码。对现有代码的任何修改对我都有好处。
use FileHandle;
opendir PAR_DIR,"D:\\PERL\\perl_programes\\parent_directory";
while (our $sub_folders = readdir(PAR_DIR))
{
next if(-d $sub_folders);
opendir SUB_DIR,"D:\\PERL\\perl_programes\\parent_directory\\$sub_folders";
while(our $file = readdir(SUB_DIR))
{
next if($file !~ m/\.html/i);
print_file_names($file);
}
close(FUNC_MODEL1);
}
close(FUNC_MODEL);
sub print_file_names()
{
my $fh1 = FileHandle->new("D:\\PERL\\perl_programes\\parent_directory\\$file")
or die "ERROR: $!"; #ERROR HERE
print("$file\n");
}
答案 0 :(得分:6)
您发布的代码看起来过于复杂。查看File::Find::Rule,你可以用很少的代码完成大部分繁重工作。
use File::Find::Rule;
my $finder = File::Find::Rule->new()->name(qr/\.html?$/i)->start("D:/PERL/perl_programes/parent_directory");
while( my $file = $finder->match() ){
print "$file\n";
}
我的意思是不那么性感吗?!
用户评论说您可能希望仅使用Depth = 2条目。
use File::Find::Rule;
my $finder = File::Find::Rule->new()->name(qr/\.html?$/i)->mindepth(2)->maxdepth(2)->start("D:/PERL/perl_programes/parent_directory");
while( my $file = $finder->match() ){
print "$file\n";
}
将适用此限制。
答案 1 :(得分:4)
您未在$file
函数中提取提供的print_file_names()
参数。
应该是:
sub print_file_names()
{
my $file = shift;
...
}
外环中的-d
测试看起来也不对,BTW。你说的是next if -d ...
,这意味着它会跳过目录的内部循环,这似乎与你需要的完全相反。它工作的唯一原因是因为你正在测试$file
,它只是相对于路径的文件名,而不是完整的路径名。
另请注意:
/
作为路径分隔符opendir($scalar, $path)
代替opendir(DIR, $path)
nb:未经测试的代码如下:
use strict;
use warnings;
use FileHandle;
my $parent = "D:/PERL/perl_programes/parent_directory";
my ($par_dir, $sub_dir);
opendir($par_dir, $parent);
while (my $sub_folders = readdir($par_dir)) {
next if ($sub_folders =~ /^..?$/); # skip . and ..
my $path = $parent . '/' . $sub_folders;
next unless (-d $path); # skip anything that isn't a directory
opendir($sub_dir, $path);
while (my $file = readdir($sub_dir)) {
next unless $file =~ /\.html?$/i;
my $full_path = $path . '/' . $file;
print_file_names($full_path);
}
closedir($sub_dir);
}
closedir($par_dir);
sub print_file_names()
{
my $file = shift;
my $fh1 = FileHandle->new($file)
or die "ERROR: $!"; #ERROR HERE
print("$file\n");
}
答案 2 :(得分:3)
答案 3 :(得分:3)
您将需要更改整个代码以使其健壮:
#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
my $top = $ENV{TEMP};
find( { wanted => \&wanted, no_chdir=> 1 }, $top );
sub wanted {
return unless -f and /\.html$/i;
print $_, "\n";
}
__END__
答案 4 :(得分:1)
您是否考虑过使用
答案 5 :(得分:0)
这是一种不需要使用File :: Find:
的方法首先打开根目录,然后使用readdir将所有子文件夹的名称存储在数组中;
然后,使用foreach循环。对于每个子文件夹,通过链接根目录和文件夹名称来打开新目录。仍然使用readdir将文件名存储在数组中。
最后一步是编写处理foreach循环内文件的代码。
特别感谢我的老师给了我这个想法:)真的很有效!