Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Finding files excluding some

by david.paige (Initiate)
on Mar 30, 2009 at 22:08 UTC ( #754262=perlquestion: print w/replies, xml ) Need Help??
david.paige has asked for the wisdom of the Perl Monks concerning the following question:

I have been reading through the File::Find threads trying to find an answer to this question, but wasn't able to quite find it. I want to write the equivalent of this ksh command in perl:
find /h -depth -type f -name *.[!ao] -print
which should find all files, except those of .a or .o I am willing to redirect them to a file, and then read that into a file. (It was difficult for me to follow the redirections for Find::File.)

I was able to get fully qualified pathnames with File::Find, but wasn't able to exclude certain extensions, and I didn't quite follow some of the redirecting of standard output. If I change the default for standard output, does it revert at some point, or do I have to manually reset it?

What just occurred to me now, is the not completely elegant solution of running a ksh script, doing the file find, and then running the perl program, reading the file list from standard input. Maybe that would be easiest....

Replies are listed 'Best First'.
Re: Finding files excluding some
by ELISHEVA (Prior) on Mar 30, 2009 at 22:16 UTC
    You may prefer File::Finder which is a wrapper around File::Find that mimics the options for the find command.

    If you choose to work directly with File::Find, keep in mind that nearly everything you would normally do on the command line with find you do inside of the visitor function ($wanted in the File::Find documentation). So if you want to exclude things by extension you would do something like this (pseudo code):

    sub doForEachFile { if ($File::Find::name !~ /\.[oa]$/) { #we have what we what ever; } }

    Best, beth

      Very minor syntax preference: If I'm looking to exclude files, I generally return from the 'wanted' function, which just reduces the level of indentation in the subroutine. For example:

      sub doForEachFile { return if $File::Find::name =~ /\.[oa]$/; #we have what we what ever; }

      Does the same thing as your code, just organized a bit differently.

Re: Finding files excluding some
by merlyn (Sage) on Mar 30, 2009 at 23:05 UTC
Re: Finding files excluding some
by Your Mother (Chancellor) on Mar 30, 2009 at 22:47 UTC

    This is only slightly tested but I think it's right-

    use File::Find::Rule; my @files = File::Find::Rule->file() ->not( File::Find::Rule->new->name("*.[!ao]") ) ->in("."); print join("\n", @files), "\n";

    File::Find::Rule. Much easier interface than File::Find (update: fixed backwards names).

    (update: thanks to afoken below; ("*.[!ao]") should not have the bang: ("*.[ao]"), and merlyn's example is probably more in line with what you're after.)

      ->not( File::Find::Rule->new->name("*.[!ao]") )

      I think there should be only one negation. As only *.a and *.o should be ignored, the inner rule should be ...->name('*.[ao]').


      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: Finding files excluding some
by Anonymous Monk on Mar 30, 2009 at 23:16 UTC
    Thank you all for the suggestions. I am eager to try them out. I'd played with the Find::File::Rule, but I guess I just needed a little nudge in the right direction.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://754262]
Approved by ELISHEVA
and the fog begins to lift...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2017-04-26 19:54 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (488 votes). Check out past polls.