3

私はPerlの初心者です。ディレクトリ (A) とそのすべてのサブディレクトリ (B、C) 内の特定の拡張子を持つすべてのファイルを削除しようとしています。特定のディレクトリに対してこれを行う方法を学びましたが、再帰的にではありません。つまり、次は A ディレクトリでジョブを実行しますが、B、C サブディレクトリではジョブを実行しません。

use strict;    
use warnings;    
my $dir = "~/A/";    
unlink glob "$dir/*.log";

私は試してみました

use strict;
use warnings;
use File::Find;
my $dir = "~/A";
find(\&wanted, $dir);
sub wanted { 
unlink glob "*.log";
}

しかし、次のメッセージが表示されますCan't stat ~/A: No such file or directory。ディレクトリがそこにある間。ヒントはありますか?マリオ

4

7 に答える 7

5

シェル固有$ENV{"HOME"}の代わりに試してみてください。~

use strict;    
use warnings;    
my $dir = "$ENV{HOME}/A";
unlink glob "$dir/*.log";
于 2013-05-27T10:42:28.343 に答える
4

2 番目のスクリプトでは、find関数内で別の検索を行わないでください。その関数は既に再帰を使用してツリーをトラバースしているためです。ファイルがログであるかどうかを単純に比較して削除します。ワンライナー:

perl -MFile::Find -e '
    find( 
        sub { m/\.log$/ and do { unlink $_ or warn qq|Could not unlink file _$\n| } 
        }, 
        shift 
    )
' .

.私の場合、現在のディレクトリで検索を開始する引数を受け入れます。

于 2013-05-27T10:51:53.170 に答える
1

Find::File は、たとえば /root/ に置き換えようとすると、「~」マークの原因に問題があるようです。

use strict;
use warnings;
use File::Find;
my $dir = "$ENV{HOME}/A";
find(\&wanted, $dir);
sub wanted {
unlink glob "*.log";
}
于 2013-05-27T11:05:13.357 に答える
1

glob子ディレクトリに再帰しない ことは正しいです。

次のコードを実行して、実行as-is内容を視覚化できるようにします。理解したら、それを$DEBUGオフにするか、コードから削除できます。

#!/usr/bin/perl

use warnings;
use strict;
use File::Find;

my $path = "$ENV{HOME}/A";
my $DEBUG = 1;

find(\&wanted, $path);

sub wanted {
    return if ! -e; 

    my $file = $File::Find::name;

    if ($DEBUG) {
        if( $file =~ /\.log$/ ) { 
            print "Log file found: $file\n"
        } else {
            print "Non-log file found: $file\n";
        }   
    } else {
        # anything that ends with '.log'
        unlink $file if $file =~ /\.log$/;
    }   
}
于 2013-05-27T16:16:13.133 に答える
0

opendir / readdir を使用できます。これは、さまざまな保持期間で複数のディレクトリを管理し、オプションで正規表現の有無にかかわらずファイルを指定するための私のソリューションです

#Add directories to be maintained "|" delimited days to keep files.
my @directories_and_retention = (
qq!$ENV{ARCDIR}|3|\\.lok\$!, #be careful
qq!$ENV{APPPATH}/ldap/logs|5!,
qq!$ENV{LOGDIR}/canary|2!,
qq!$ENV{LOGDIR}/metadata|30!,
qq!$ENV{LOGDIR}/archive|45!
);

foreach my $directory (@directories_and_retention) {
        my ($path,$retention_days,$file) = split(/\|/,$directory);

        opendir (DIR, "$path");
        my @logfiles = readdir(DIR);
        closedir (DIR);

        foreach $logfile (@logfiles) {
                next if ($logfile =~ /^\.\./);
                next if ($logfile =~ /^\./);
                next if (-d "$path/$logfile");

                if ($file) {
                        next unless ($logfile =~ /$file/);
                }

                if (-M "$path/$logfile" > $retention_days) {
                        print "$path/$logfile > $retention_days\n";
                        unlink("$path/$logfile");
                }
        }
}
于 2014-12-18T14:58:55.740 に答える
0

Linux で実行していますか? もしそうなら、私は役立つかもしれない別の解決策を持っています. 必要な言語を述べずに、問題は「特定の拡張子を持つすべてのファイルを削除し、再帰的に実行する必要がある」ことに基づいています。これがより大きな作業の一部である場合は、私の答えを無視してください。管理を行っているだけの場合は、うまくいく可能性があります。

find . -type f -name "*.ext" -exec rm {} \;

これにより、現在のディレクトリとその下にあるすべてのファイルが検索され、それらのパスが rm コマンドに渡されます。

于 2013-05-27T10:52:29.803 に答える