Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Recursive search and delete

by qwerty80 (Initiate)
on Nov 16, 2012 at 06:26 UTC ( #1004138=perlquestion: print w/ replies, xml ) Need Help??
qwerty80 has asked for the wisdom of the Perl Monks concerning the following question:

Hello All, I m trying to search for a particular *.xml files and then delete it from a directory. following code is throwing me an error. help me..
#!/usr/bin/perl use strict; my $file = "abc*.xml*"; my $searchdir = "/tst"; readDirectory($searchdir, $file); sub readDirectory { my $searchdir = shift; my $searchfile = shift; print "Searching in $searchdir \n"; # Open and close the directory opendir DIR, $searchdir or die("An error occured: $!"); my @files = readdir(DIR); closedir DIR; foreach my $currentFile (@files) { next if $currentFile =~ /^\./; if ( $currentFile eq $searchfile ) { print "Found the file: $searchdir/$curre +ntFile n"; unlink($file); } if ( -d "$searchdir/$currentFile" ) { readDirectory("$searchdir/$currentFile", $searchfile); } } }

Comment on Recursive search and delete
Download Code
Re: Recursive search and delete
by NetWallah (Abbot) on Nov 16, 2012 at 06:53 UTC
    Please use <code> tags to preserve format for your code </code>.

    Your statement:

    if ( $currentFile eq $searchfile )
    Looks for an exact string match between the $currentFile and "abc*.xml*".

    It is unlikely to find a file with that name.
    You could use regular expressions to match the file name, but I would recommend re-designing your code around the File::Find module and friends (File::Find::Match).

                 "By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest."           -Confucius

Re: Recursive search and delete
by tobyink (Abbot) on Nov 16, 2012 at 09:36 UTC

    The error is as NetWallah says, that you are checking to see if the filename equals "abc*.xml*" - not if the filename matches that pattern.

    Personally I'd use Path::Class::Rule...

    # untested! use strict; use warnings; use Path::Class::Rule; my $rule = Path::Class::Rule->new->file->name("abc*.xml*"); $_->remove for $rule->all("/tst");
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Recursive search and delete
by Tommy (Chaplain) on Nov 16, 2012 at 10:06 UTC

    Untested:

    use File::Util; unlink for grep { $_ =~ /xml$/i } File::Util->new->list_dir('/your/directory', '--recurse');

    Or alternately:

    use File::Util; $f = File::Util->new(); unlink for grep { $_ =~ /xml$/i } $f->list_dir('/your/directory', '--r +ecurse');
    --
    Tommy
    $ perl -MMIME::Base64 -e 'print decode_base64 "YWNlQHRvbW15YnV0bGVyLm1lCg=="'
Re: Recursive search and delete
by zentara (Archbishop) on Nov 16, 2012 at 10:54 UTC
    And a File::Find example: ( the regex probably needs improvement :-) )
    #!/usr/bin/perl # delete all of the *.xml* files recursively use File::Find qw(find); @ARGV = qw(.) unless @ARGV; find sub { return unless -f; return unless $_ =~ /(.*).xml(.*)/; unlink $_ and warn "deleted $_\n"; }, @ARGV; # it would be good to show all dirs to be deleted # and promp user for 'yes' __END__

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: Recursive search and delete
by roboticus (Canon) on Nov 16, 2012 at 11:16 UTC

    qwerty80:

    You already have several good answers, so I'm not really adding much. However, I've not played much with opendir or readdir and I thought I'd like to play with them a bit. I didn't want a recursive solution, so I did it this way:

    $ cat 1004138.pl #!/usr/bin/perl use strict; use warnings; use 5.10.0; use autodie; my $filespec = "abc*.xml"; my @dirs = ('ABC'); while (@dirs) { my $curdir = pop @dirs; opendir(my $dh, $curdir); for my $f (readdir($dh)) { next if $f =~ /^\.\.?$/; next unless -d "$curdir/$f"; print "pushing $curdir/$f\n"; push @dirs, "$curdir/$f"; } for (glob("$curdir/$filespec")) { print "processing $_\n"; } } $ perl 1004138.pl pushing ABC/DEF pushing ABC/GHI pushing ABC/JKL processing ABC/abcde.xml processing ABC/JKL/abc_x.xml processing ABC/JKL/abc_y.xml processing ABC/JKL/abc_z.xml pushing ABC/GHI/baz pushing ABC/GHI/foo pushing ABC/GHI/bar processing ABC/GHI/abc_5.xml processing ABC/GHI/abc_6.xml processing ABC/GHI/bar/abc_1.xml processing ABC/GHI/bar/abc_2.xml processing ABC/GHI/bar/abc_3.xml processing ABC/GHI/bar/abc_4.xml processing ABC/GHI/foo/abc_8.xml processing ABC/GHI/foo/abc_9.xml processing ABC/GHI/foo/abc_a.xml processing ABC/GHI/foo/abc_b.xml processing ABC/GHI/baz/abc_{7}.xml

    It's not particularly pretty, but it amused me for a few minutes. I didn't actually let it do file deletions because I'm loath to do automatic deletes until I've well tested such a script. It's a good thing, too. On my earlier attempt, a pair of bugs conspired to make the script "process" all "abc*.xml" files on my hard drive, rather than just those in the ABC directory.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      "I didn't actually let it do file deletions because I'm loath to do automatic deletes until I've well tested such a script."

      One nifty trick I sometimes use in situations like that is to make my script output text like this to STDOUT:

      rm ABC/JKL/abc_x.xml rm ABC/JKL/abc_y.xml rm ABC/JKL/abc_z.xml

      Then when I've played with it a few times, and I'm confident it's outputting the right commands, pipe the output into sh:

      perl myscript.pl | sh

      This is also good if you need to do a bunch of complex database changes. Just write SQL to STDOUT, and once you're sure it's OK, pipe it into your favourite command-line SQL tool.

      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Recursive search and delete
by Arunbear (Parson) on Nov 16, 2012 at 11:59 UTC
    For this task you probably don't need to resort to Perl e.g. using the standard command line tools
    find -name 'abc*xml' | xargs rm
    would accomplish the same.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1004138]
Approved by shmem
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2014-12-29 04:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (184 votes), past polls