2017-09-03 57 views
0

我在通过我的文件系统遍历时遇到问题,使我的Perl脚本识别了一些子目录。Perl脚本无法识别所有使用-d标志的目录

请注意,这是一个家庭作业的一部分,我无法用任何一种模块。我试图自己解决这个问题很长一段时间,现在我处于一个障碍之中。

我试图遍历文件结构,捕获所有的文件,目录和子目录的名称为各自对应的数组,并打印出来,如下所示格式:

Directory: ./ 
Files: file1.text file2.pl file3.text 
Directories: subdir1 subdir2 subdir3 

Directory: subdir1 
Files: file3.text file4.pl 
Directories: subdir42 

.. 。等等。

我试图使用递归作为解决这一点,但我的老师表示,递归是不是来处理这个问题的适当方式。

我已成功地打印,以适当的格式,当前的工作目录,以及当前工作目录的子目录。

出于某种原因,当我改变当前的代码块

if (-d $entry){ 
     next if $entry =~/^\./; 
     push(@subdirs,"$entry"); 
     push(@dirs,"$currdir/$entry"); 
     } 

     elsif(-f $entry) { 
     push(@files,"$entry"); 
     } 

它会省略一些子目录。

请参阅下面的整个脚本。

#!/usr/bin/perl 
use strict; 
use warnings; 


sub traverse { 

my @dirs = ('.'); 
my @subdirs; 
my @files; 
    while(my $currdir = shift @dirs){ 

    opendir(my $dirhandle, $currdir) or die $!; 

     while(my $entry = readdir $dirhandle){ 

     if (-d -r $entry){ 
     next if $entry =~/^\./; 
     push(@subdirs,"$entry"); 
     push(@dirs,"$entry"); 
     } 

     else { 
     push(@files,"$entry"); 
     } 

    } 
     print "Directory: $currdir\n"; 
     print "Directories: "; 
     print "@subdirs"; 
     print"\n"; 


     print "Files: "; 
     foreach my $curfile (@files) { 
      next if $curfile eq '.' or $curfile eq '..'; 

      if ($curfile =~ /(\S*\.delete)/){ 
        unlink "$currdir/$curfile"; 
      } 

      $curfile =~ s/txt$/text/; 
      print "$curfile "; 
     } 

    print "\n"; 
    close $dirhandle; 
    undef @files; 
    undef @subdirs; 

} 
return; 
} 
traverse(); 

电流输出:

Directory: . 
Directories: test dir_3 test2 
Files: recursion.text count_files.pl testing.text thelastone.pl testing.pl prog5_test.pl program51.pl program5.pl recursion.pl recurse.text prog52.pl 
dirs.pl 

Directory: test 
Directories: 
Files: testfile1.text prog5_test.pl stilltesting program5.pl testfile2.text dirs.pl 

Directory: dir_3 
Directories: 
Files: 

Directory: test2 
Directories: 
Files: file2.text moretesting file3.text 

stilltestingmoretesting应认定为目录。

+1

你正在检查'-r' - 如果不是,它是一个文件?这看起来很奇怪 - 你应该检查它是一个目录还是一个文件 - 它是否可读是另一个值得单独处理的问题。 – bytepusher

+0

您应该更仔细地布置您的代码:您的缩进遍布整个地方。另外,你应该从'“$ entry”中删除引号,因为它们是不必要的,并且在某些情况下可能会导致问题。 – Borodin

+1

谢谢@Borodin,你是对的。我已根据您的建议修改了脚本。 –

回答

0
if (-d $entry) 

应该

if (-d "$currdir/$entry") 

$entry只是一个目录的名称。 -d需要一个实际路径。

+0

含义'-d -r $ entry'应该是'-d $ entry'应该是'-d'$ currdir/$ entry“'。我希望在做一个单独的'-r $ entry'(作为警告或例外)之后他会看到这个。说实话,我并不完全确定作业政策。 – bytepusher

+0

谢谢@melpomene,这正是我所错过的。脚本现在按预期工作。 –

+0

@bytepusher,'-d -r“$ currdir/$ entry”'很好。从5.10开始,它意味着'-d“$ currdir/$ entry”&& -r“$ currdir/$ entry”' – ikegami

相关问题