How can I use Perl, how can I find and delete files with a specific suffix?

I need to write a function in Perl that removes all files with a suffix .rc

in a specific location and its subdirectories (lets call it targetroot).

I work in NT env, so I cannot use system commands like find

or rm

. I got tired of doing it with tripping and finding options but failed.

I tried:

print "\n<<<    Removing .rc files from $targetRoot\\20140929_231622    >>>\n";
my $dir = "$targetRoot\\20140929_231622";
find(\&wanted, $dir);
sub wanted 
{ 
  unlink glob "*.rc";
}

      

Can someone show me how to do this?

+3


source to share


6 answers


You're pretty close. File::Find

is a tool for working here. Try to put it wanted()

like this:

sub  wanted {
    # $_ set to filename; $File::Find::name set to full path.
    if ( -f and m/\.rc\z/i ) {
        print "Removing $File::Find::name\n"; 
        unlink ( $File::Find::name );
    }
}

      



Try it first without tripping, of course, to make sure you're getting the right goals. Remember that File::Find

will drop the directory structure by default.

+3


source


You need to change the subroutine wanted

:

sub wanted { /\.rc$/ && ( unlink $File::Find::name or die "Unable to delete $_: $!" ) }

      




From File::Find

documentation

Function wanted

The function wanted()

performs whatever checks you want on each file and directory. Note that, despite its name, the wanted()

function is a generic callback function and does not tell File::Find

if a file is "needed" or not. In fact, its return value is ignored.

The required function takes no arguments, but does its job through a set of variables.

`$File::Find::dir` is the current directory name,

`$_` is the current filename within that directory

`$File::Find::name` is the complete pathname to the file.

      

+2


source


Path :: Class makes it a little nicer:

#!/usr/bin/env perl

use strict;
use warnings;

use Path::Class;

run(@ARGV ? \@ARGV : ['.']);

sub run {
    my $argv = shift;
    my $dir = dir(shift @$argv)->resolve; # will croak if path does not exist
    $dir->recurse(callback => \&rm_if_rcfile);
    return;
}

sub rm_if_rcfile {
    my $entity = shift;
    return if $entity->is_dir;
    return unless $entity =~ / [.] rc \z/ix;
    print "$entity\n";
    return; # remove this line to actually delete
    unless ($entity->remove) {
        warn "'$entity' failed: $!\n";
    }
}

      

+2


source


Using File::Find

:

use strict;
use warnings;
use autodie;

use File::Find;

my $dir = "targetRoot\\20140929_231622";

find(
    sub {
        unlink if -f && /\.rc$/i;
    },
    $dir
);

      

Or using File::Find::Rule

:

use strict;
use warnings;
use autodie;

use File::Find::Rule;

my $dir = "targetRoot\\20140929_231622";

for ( File::Find::Rule->file()->name('*.rc')->in($dir) ) {
    unlink;
}

      

+1


source


Try this block of code:

my $dir = "$targetRoot\\20140929_231622";
#subroutine call
wanted($dir);

#subroutine declaration
sub wanted 
{ 
    my $result = $_[0];

  my @p = grep {-f} glob("$result\\*.rc");
  foreach my $file (@p)
   {
     print "Removing files $file from the directory $dir" . unlink($file) . "\n";

    }
}

      

0


source


Besides the definition $targetRoot

, all you have to do is change your wanted

sub.

File::Find

calls wanted

for every node (file or directory) it finds under the root directory you specify. It will put basename (the name of the bare file without path information) in $_

and execute chdir

in the directory that contains it.

Since the default action unlink

- if you don't pass a parameter - is to delete the file specified $_

, all you have to do is check that it is a file and ends with .rc

.

This version wanted

will do it for you.

sub wanted { 
  unlink if -f and /\.rc\z/i;
}

      

And this subroutine is so short that you can use an anonymous subroutine in the call find

. Here's the full version, which also warns that the deletion failed on any file.

use strict;
use warnings;

use File::Find;

my $targetRoot = 'C:\path\to\root';
my $dir        = "$targetRoot\\20140929_231622";

print qq{\n<<<    Removing .rc files from "$dir"    >>>\n};

find(sub {
  -f and /\.rc\z/i and unlink or warn qq{Unable to delete "$File::Find::name"\n};
}, $dir);

      

0


source







All Articles