2017-09-03 59 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

相關問題