Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

File Find

by oaklander (Acolyte)
on Mar 13, 2002 at 11:34 UTC ( [id://151348]=perlquestion: print w/replies, xml ) Need Help??

oaklander has asked for the wisdom of the Perl Monks concerning the following question:

My script will ask for an absolute path and give me all the files and Directories and subdirectories and tell me which are files and which are directories. It then gives statistics at the end. Now I want to change it where it will prompt me for an absolute path AND a specific name to search for.

After I put in the name it should list all the files/directories/subdirectories with the name and give the stats at the end.
use File::Find qw(finddepth); #finddepth is a perl reserved word die "GIVE DIRECTORY NAME AS AN ARGUMENT\n" unless @ARGV; *name = *File::Find::name; finddepth \&list, @ARGV; sub print2 { $LINEMAX=2; #SETS HOW MANY LINES OF OUTPUT PER C/R if(++$line > $LINEMAX) { $line=0; getc; } print @_; } if ( !-d ) { print "DIRECTORY NOT FOUND!\n"; exit(0); } else { sub list { if (!-l && -d _) { print2; $i++; print "$name is a DIRECTORY\n"; } else { $j++; print2; print "$name\n"; } } $x=$i+$j; print "\nDIRECTORY COUNT = $i\n"; print "FILE COUNT = $j\n"; print "TOTAL RECORD COUNT = $x\n"; }

My last part of the output (I cut out the first 200 lines of output) for this script is:
/Perl/bin/newr/hh.txt.bak /Perl/bin/newr/scr.pl /Perl/bin/newr/scr.txt /Perl/bin/newr/scr.txt.bak /Perl/bin/newr is a DIRECTORY /Perl/bin is a DIRECTORY DIRECTORY COUNT = 3 FILE COUNT = 209 TOTAL RECORD COUNT = 212

Replies are listed 'Best First'.
Re: File Find
by strat (Canon) on Mar 13, 2002 at 11:59 UTC
    Hello,

    there are more than one ways to do it...

    1. Call the programm with a parameterlist where the last is the filename you are looking for and remove this name before starting find with my $filename = pop(@ARGV); and then compare each found filename with $filename

    2. Use named parameters, e.g. with the Getopt::* - modules (e.g Getopt::Long) 3. Use named parameters and care for them by yourself, e.g.

    scriptname.pl --dir="/dir1/sdir1" --dir="/dir2/sdir2" --file="thisfile +.txt"
    I don't know if there are modules that handle this case. If not, you could do it like the following:
    my $params = &GetParameters(); my @dirs = @{ $params->{dir} }; my @file = @{ $params->{file} }; # and so on sub GetParameters { my @allowedParams = qw(file dir); die &PrintUsage() unless @ARGV; my $params = {}; # shell contain parameters foreach (@ARGV){ my ($key, $val) = split(/\=/, $_, 2); # split up by the first = # test if $key is a valid parameter unless ($key =~ s/^\-\-//) { # must start with -- die "Error: invalid param $key\n"; } unless ( grep {lc($key) eq lc($_)} @allowedParams){ die "Error: param $key not allowed\n"; } # maybe do some checks if $val is existing .... # add param to hashreference $params push (@{ $params->{$key} }, $val); } # for return ($params); } # GetParameters
    But before you use this code (which I haven't tested), better look if there's a module on CPAN that solves this problem.

    Btw: i think programming with use strict; and use warnings; might be a very good idea, because it is much easier to find "silly" and "not-so-silly" errors that way

    Best regards,
    perl -le "s==*F=e=>y~\*martinF~stronat~=>s~[^\w]~~g=>chop,print"

      Ran the script as mentioned and seem to get errors about around the &PrintUsage area. I tried using just die "print error\n" and still getting errors. Please advise on how I can get this to work?

        You would, of course, have to implement the PrintUsage subroutine. Adding something like this to the top should do the trick:

        sub PrintUsage{ print <<USAGE This is where you would type the error message that you want displayed if someone passes arguments to your script that you haven't specified, or if the syntax is wrong, etc. USAGE ; }
Re: File Find
by Juerd (Abbot) on Mar 13, 2002 at 11:49 UTC

    You didn't ask for a code review, but I can't stop myself from making a few observations.

    finddepth Is not a reserved word, you must include it in the list, so it can be exported to your package. That way, you can use just "finddepth" instead of "File::Find::finddepth", without also importing find().

    Your code has no indentation. Indents make code a lot easier to read. If you want people to help with your code, it's generally a good idea to make sure they can read it :)

    You have an awful lot of ALLCAPS words, which can be quite annoying.

    A sub in an if's else block in another sub isn't going to make reading or maintaining the code any easier.

    The script has some small problems, but it's a nice obfuscation.

    U28geW91IGNhbiBhbGwgcm90MTMgY
    W5kIHBhY2soKS4gQnV0IGRvIHlvdS
    ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
    geW91IHNlZSBpdD8gIC0tIEp1ZXJk
    

Re: File Find
by strat (Canon) on Mar 13, 2002 at 15:36 UTC
    I've just tested the program, and added the idea from Mull
    #!perl -w use strict; my $params = &GetParameters(); my @dirs = @{ $params->{dir} }; my @file = @{ $params->{file} }; print "\nDIRS:\n\t"; print join("\n\t", @dirs); print "\nFILES:\n\t"; print join("\n\t", @file); # and so on sub GetParameters { my @allowedParams = qw(file dir); die &PrintUsage() unless @ARGV; my $params = {}; # shell contain parameters foreach (@ARGV){ my ($key, $val) = split(/\=/, $_, 2); # split up by the first = # test if $key is a valid parameter unless ($key =~ s/^\-\-//) { # must start with -- die &PrintUsage( "Error: invalid param --$key"); } unless ( grep {lc($key) eq lc($_)} @allowedParams){ die "Error: param $key not allowed\n"; } # maybe do some checks if $val is existing # .... # add param to hashreference $params push (@{ $params->{$key} }, $val); } # for return ($params); } # GetParameters # Added &PrintUsage; thx to [mull] sub PrintUsage{ my $msg = shift || ''; return (<<USAGE); $msg: $0 --dir=/dir1/sdir2 --dir=/dir2/sdir2 --file=README.txt USAGE ; }
    Output:
    C:\TEMP\test>testParameters.pl --dir=/dir1/sdir2 --dir=/dir2/sdir2 --f +ile=README.txt DIRS: /dir1/sdir2 /dir2/sdir2 FILES: README.txt C:\TEMP\test>

    Best regards,
    perl -le "s==*F=e=>y~\*martinF~stronat~=>s~[^\w]~~g=>chop,print"

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (7)
As of 2024-03-28 18:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found