15

I am currently reading a file and storing the data in an array named @lines. Then, I loop through this array using a for loop and inside the loop I match on certain values:

$find = "fever";

if ($_ =~ /$find/) {
    print "$_\n";
    $number++;
    #@lines =
    #print ("there are : " . $number);
}

At the moment, I am using a scalar, $find, with a value of fever instead of performing the repetitive statements for each filter.

Can I pass an array for comparison instead of a scalar keyword?

4 Answers 4

33

If you read a file into a list it will take everything at once

@array = <$fh>;  # Reads all lines into array

Contrast this with reading into a scalar context

$singleLine = <$fh>;  # Reads just one line

Reading the whole file at once can be a problem, but you get the idea.

Then you can use grep to filter your array.

@filteredArray = grep /fever/, @array;

Then you can get the count of filtered lines using scalar, which forces scalar (that is, single value) context on the interpretation of the array, in this case returning a count.

print scalar @filteredArray;

Putting it all together...

C:\temp>cat test.pl
use strict; use warnings;  # always

my @a=<DATA>;  # Read all lines from __DATA__

my @f = grep /fever/, @a;  # Get just the fevered lines

print "Filtered lines = ", scalar @f;  # Print how many filtered lines we got

__DATA__
abc
fevered
frier
forever
111fever111
abc

C:\temp>test.pl
Filtered lines = 2
C:\temp>
Sign up to request clarification or add additional context in comments.

1 Comment

This would be a better answer if it clarified how to get a filehandle for an arbitrary file, say if you have a filename in $filename. DATA is a new one on me, by the way, but I've never been more than a casual Perl user.
5

If you have Perl 5.10 or later, you can use smart matching (~~) :

my @patterns = (qr/foo/, qr/bar/);

if ($line ~~ @patterns) {
    print "matched\n";  
}

Comments

5

You could also use the File::Slurp module, which is convenient.

use strict;
use warnings;
use File::Slurp 'read_file';

my $fname = shift or die 'filename!';
my @lines = grep /fever/, read_file $fname; # grep with regular expression
print @lines;

If you're new to Perl, take a look at the map and grep operators, which are handy for processing lists.

Also, take a look at the ack utility, which is a great replacement for find/grep. (Actually, it's a superior alternative.)

Comments

5

Use Tie::File. It loads the file into an array, which you can manipulate using array operations. When you untie the file, its components will be saved back in the file.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.