Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Is there a better way.

by Anonymous Monk
on Feb 23, 2009 at 22:39 UTC ( [id://745849]=perlquestion: print w/replies, xml ) Need Help??

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

Just curious if there is a faster way to do this. To loop, match and add to the array. I am loading a list of files into an array, then matching based on a unique number and storing that into another array.
my $caseNumber = $ARGV[0]; my $pattern = "(.*?)$caseNumber(.*?)"; my $count = 0; my @uploads; my @files; ##Open logfiles directory and read into array. opendir DIR, "Directory" or die "Unable to open Directory, please try +again"; @files = readdir(DIR) or die "Unable to read directory"; closedir DIR; ##Loop though the files and if the pattern matches, push it into the a +rray. foreach (@files) { if (/$pattern/) { push @uploads,$_; } }

Replies are listed 'Best First'.
Re: Is there a better way.
by Roy Johnson (Monsignor) on Feb 23, 2009 at 22:42 UTC
    @uploads = grep /$pattern/, @files; ?

    Caution: Contents may have been coded under pressure.
      Thanks I will give that a try.

      The way I normally do this is similar, but skips using the temporary @files array.

      opendir my $dh, $dir or die "Unable to opendir [$dir]: $!"; my @uploads = grep /$pattern/, readdir ($dh); closedir $dh;

      Sometimes I will add a map { "$dir/$_" } between = and grep, but it depends on the use.

      l8rZ,
      --
      andrew
Re: Is there a better way.
by ig (Vicar) on Feb 23, 2009 at 23:42 UTC
    Maybe:
    chdir(Directory) or die "Directory: $!"; @uploads = glob("*$caseNumber*");
    or
    my @uploads = map { $_ =~ m!.*/(.*)! } glob("Directory/*$caseNumber*") +;
    If your directory or $caseNumber have spaces in them then you will want bsd_glob, which you can get by:
    use File::Glob qw(:glob);
Re: Is there a better way.
by Illuminatus (Curate) on Feb 23, 2009 at 22:57 UTC
    Do you really want the code to run faster, or are you just looking for a more elegant solution?
    my $caseNumber = $ARGV[0]; my $dir="directory"; my @files=`ls $dir/*$caseNumber*`; # will leave newlines
    6 of one...

      Instead of running an external program to get a list of file names just use Perl's built-in glob function:

      my @files = glob "$dir/*$caseNumber*";

        Without digressing too much, why is it better to use Perl's built-in functions?

        And you didn't even know bears could type.

Re: Is there a better way.
by ysth (Canon) on Feb 24, 2009 at 03:18 UTC
    my $caseNumber = $ARGV[0]; my $pattern = "(.*?)$caseNumber(.*?)";
    The ending (.*?) is pointless there. It's saying "must match ..., followed by zero or more characters". Since there will always be zero or more characters, just leave it off.

    And unless case numbers are a fixed length and distinguishable from the surrounding parts of the filename, that's not a good thing to do, since a case number "13" will match a file for case number "113", "130", etc.

Re: Is there a better way.
by tokpela (Chaplain) on Feb 24, 2009 at 09:41 UTC

    I don't see the solution of pulling into an initial @files array scalable.

    I would iterate over the directory handle - what if you want to search a directory that has thousands of files (ie lots of memory)?

    my $caseNumber = $ARGV[0]; my $pattern = "(.*?)$caseNumber(.*?)"; my $count = 0; my @uploads; ##Open logfiles directory opendir DIR, "Directory" or die "Unable to open Directory, please try +again"; while (my $filename = readdir(DIR)) { if ($filename =~ /$pattern/) { my $filepath = "$directory/$filename"; # make full filepath push(@uploads, $filepath); } } closedir DIR; $count = scalar(@uploads);

    Also, I added the directory to the filename since I imagine that you will probably want to access the files at some point from the array.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (6)
As of 2024-03-29 13:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found