简体   繁体   中英

Using Find::File::Rule to find Perl scripts and exclude .bak files

I am using Find::File::Rule to find Perl scripts. I want to exclude certain files, like test files and backup files, but I cannot make it exclude *.bak files if they start with a dot, for example ( p.pl ):

use warnings;
use strict;
use Data::Dump;
use File::Find::Rule;

open(my $fh,">",".c.bak");
print $fh "#! /usr/bin/env perl\n";
close($fh);

my $rule = File::Find::Rule->new;
$rule->or(
    $rule->new->name('*.bak')->prune->discard,
    $rule->new->grep( qr/^#!.*perl\s*$/, [ sub { 1 } ] )
   );
my @files=$rule->in(".");
dd @files;

This gives output:

("p.pl", ".c.bak")

whereas expected output should be:

"p.pl"

The problem here is that files prefixed with a dot aren't matched by the '*.bak' quantifier, because they're 'hidden' files.

If you chdir to your directory and do echo * or echo *.bak you won't see the file there either. So effectively - that rule isn't matching, because it's a hidden file.

Solutions would be:

  • new rule to explicitly match '.' files.
  • regular expression match to 'name' would do the trick

Something like:

$rule->new->name(qr/\.bak$/)->prune->discard,

You just have to add another filter rule for the hidden backup files:

#!/usr/bin/perl

use warnings;
use strict;
use Data::Dump;
use File::Find::Rule;

open(my $fh,">",".c.bak");
print $fh "#! /usr/bin/env perl\n";
close($fh);

my $rule = File::Find::Rule->new;
$rule->or(
    $rule->new->name('*.bak')->prune->discard,
    $rule->new->name('.*.bak')->prune->discard,            # <== hidden backups
    $rule->new->grep( qr/^#!.*perl\s*$/, [ sub { 1 } ] )
   );
my @files=$rule->in(".");
dd @files;

Notice the starting . in the pattern. This script will produce:

"p.pl"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM