2016-10-11 60 views
1

Perl新手,只用了3次。我需要從父目錄中刪除文件和子文件夾,當它們超過一週的時間。我在使用-M之前刪除了文件,但從未使用子文件夾。當我運行下面的詳細信息時,沒有文件從子文件夾中刪除,並且子文件夾中存在一週以上的文件。對於子文件夾中的所有文件,測試消息顯示'myAge'爲零。不知道我錯過了什麼。任何援助將非常感激。使用Perl刪除子文件夾和文件#

msg ("\n"); 
msg ("Start: \n"); 


my $parent = 'C:/temp/XYZ'; 
my ($par_dir, $sub_dir); 

opendir($par_dir, $parent); 
msg " parent is $parent \n"; 

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 
    next unless (-M $subfolder < 7 ); 

    msg " subfolder is $sub_folders is old enough to delete \n"; 

    opendir($sub_dir, $path); 
    while (my $file = readdir($sub_dir)) { 

    # for testing  
    my $myAge = (-M $file) ; 
    msg " age ... $myAge __ file ... $file\n" ;  

     if (-M $file > 7 ) { 
     msg " going to delete this file... $file \n"; 
     } else { 
     msg " will keep this file not old enough $file\n"; 
     } 

    } 
    closedir($sub_dir); 
} 
closedir($par_dir); 
+0

'msg()'函數來自哪裏? – simbabque

+0

除非(-M $ path <7);否則不應該爲'next除非(-M $子文件夾<7);'爲'而'-M $ file'是'-M「$ path/$ file」'? ['readdir'](http://perldoc.perl.org/functions/readdir.html)只返回一個文件或目錄名(沒有它的父目錄)。 – PerlDuck

+0

msg()寫入日誌文件,對不起,因爲沒有引用早期 – Fondah

回答

0

如果這真的只是第三次使用Perl,那麼恭喜!但也有一些問題,在您的代碼:

  • 始終添加use strict;use warnings;到您的代碼。這會警告(超出其他人)關於 未定義的變量並消除常見錯誤。
  • 您有一個錯字$sub_folders$subfolderuse strict;use warnings;會顯示。
  • readdir的返回值不包含父目錄。該docs說:

    如果您打算filetest返回值了READDIR的,你最好預先準備 有問題的目錄。否則,因爲我們沒有chdir, 它會測試錯誤的文件。

    我想這正是發生在這裏。

我改變了一下你的代碼,把目錄放在文件名前面,它現在似乎工作。 我還寫了一個msg函數,只是print是給定的參數。如果您擁有「真實」msg函數,則您將省略該 。

#!/usr/bin/env perl 

use strict; 
use warnings; 

sub msg 
{ 
    print @_; 
} 

msg("\n"); 
msg("Start: \n"); 

my $parent = 'C:/temp/XYZ'; 
my ($par_dir, $sub_dir); 

opendir($par_dir, $parent) or die "cannot opendir $parent: $!\n";; 
msg " parent is $parent \n"; 

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 
    next unless (-M $path < 7); 

    msg " subfolder is $sub_folders is old enough to delete \n"; 

    opendir($sub_dir, $path) or die "cannot opendir $path: $!\n"; 
    while (my $file = readdir($sub_dir)) { 

     # for testing 
     my $myAge = (-M "$path/$file"); 
     msg " age ... $myAge __ file ... $path/$file\n"; 

     if (-M "$path/$file" > 7) { 
      msg " going to delete this file... $path/$file \n"; 
     } else { 
      msg " will keep this file not old enough $path/$file\n"; 
     } 

    } 
    closedir($sub_dir); 
} 
closedir($par_dir); 

在這段代碼中可以改進一些東西。

  1. 我不會檢查目錄中的修改時間並刪除next unless (-M $path < 7);。 我的印象是,目錄的屬性(大小,時間)隨意改變 - 至少我不能想出一個模式,但也許我太愚蠢了。
  2. 爲加快速度,-X運算符(如-d,-M等)會緩存最後一個文件的結果。因此,而不是寫

    next unless (-d $path); 
    next unless (-M $path < 7); 
    

    可以

    next unless (-d $path); 
    next unless (-M _ < 7); # the '_' means: get '-M' of $path 
    

    詳見-X。基本上,-X一次獲取給定文件的所有屬性(如大小,類型,訪問時間,修改時間等)。如果在後續調用中將下劃線_作爲 文件名傳遞,則會返回前一個調用的結果(具有實際文件名),並保存另一個(昂貴的)系統調用。

  3. 算法只考慮起始目錄下的一個目錄,即它不能遞歸地工作。 取決於你真正想要什麼,這可能會也可能不會。

+0

謝謝你的細節非常有幫助! – Fondah

+0

@Fondah不客氣。再一次:如果它真的是你的第三個劇本,那麼你一定有一些天賦。用於顯示[mcve]的+1。 – PerlDuck

1

假設你在* nix系統上..

有時更容易只是調用找到

find /foo/bar/ -type d -mtime +7 -exec rm -rf {} \; 

find /foo/bar/ -type f -mtime +7 -exec rm {} \; 

將刪除所有7天前(d)irectories或(f) iles

+0

不錯,但是在問題中加上'my $ parent ='C:/ temp/XYZ';'加上頭部行中的_」... in Perl「_我假設OP正在尋找一個純粹的Perl解決方案。 – PerlDuck

+0

OK,使用模塊File:Find then。我想這是「cpanm安裝文件:找到」,如果你有cpan減去安裝。 (http://perldoc.perl.org/File/Find.html) –

+0

這將運行在Windows中,謝謝 – Fondah

相關問題