2016-10-11 2 views
1

Perlを初めて使うと、3回しか使用されません。私は親ディレクトリからファイルとサブフォルダを削除する必要があります。私は-Mを使う前にファイルを削除しましたが、サブフォルダを使ったことはありません。下の詳細を実行すると、サブフォルダからファイルが削除されず、サブフォルダに1週間以上前のファイルが存在します。テストメッセージは、サブフォルダ内のすべてのファイルに対して '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 $ subfolder <7); '(-M $ path <7);'を除いて 'next 'にしないでください。 '-M $ file'は' -M "$ path/$ file" 'ですか? ['readdir'](http://perldoc.perl.org/functions/readdir.html)はファイルまたはディレクトリ名(親ディレクトリなし)のみを返します。 – PerlDuck

+0

msg()はログファイルに書き込みます。以前は – Fondah

答えて

0

これは本当にPerlを使用する3回目の場合、おめでとうございます!しかし、いくつかの問題があなたのコードにあります。

  • 常には、あなたのコードにuse strict;use warnings;を追加します。これにより、未定義の変数 について警告(他のものを超える)し、一般的なエラーを排除します。
  • $sub_foldersと入力してください。$subfolderです。 use strict;およびuse warnings;がこれを示しています。
  • 戻り値readdirには、親ディレクトリは含まれません。 docsは言う:

    あなたが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); 
    

    を書くのあなた詳細については-Xを参照してください

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

    を書くことができます。基本的には-Xは、指定されたファイル(サイズ、タイプ、アクセス時間、変更時刻など)のすべての属性を一度に取得します。後続の呼び出しでを ファイル名として渡すと、前回の呼び出し(実ファイル名付き)が返され、別の(高価な)システムコール が保存されます。

  3. アルゴリズムでは、開始ディレクトリ以下の1つのディレクトリのみが考慮されます。つまり、再帰的には機能しません。 あなたが実際に望むものによっては、これはOKかもしれません。

+0

非常に参考にしていただきありがとうございます! – Fondah

+0

@フォンダようこそ。もう一度:もし本当にあなたの第三のスクリプトだったら、あなたはいくつかの才能を持っていなければなりません。 +1は[mcve]を表示するためのものです。 – 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)

+0

良いですが、質問の中で' my $ parent = 'C:/ temp/XYZ'; 'とPerlの_私はOPが純粋なPerlソリューションを探していると仮定します。 – PerlDuck

+0

OK、モジュールFile:Findを使用します。私はあなたがcpanのマイナスがインストールされている場合、それは "cpanm install file:find"だと思います。 (http://perldoc.perl.org/File/Find.html) –

+0

これはWindowsで動作します。ありがとうございます – Fondah

関連する問題