From a list, you want only the elements that match certain criteria.
This notion of extracting a subset of a larger list is common. It's how you find all engineers in a list of employees, all users in the "staff " group, and all the filenames you're interested in.
Use
grep
to apply a condition to all elements in the list and return only those for which the condition was true:
@MATCHING = grep { TEST ($_) } @LIST;
This could also be accomplished with a
foreach
loop:
@matching = (); foreach (@list) { push(@matching, $_) if TEST ($_); }
The Perl
grep
function is shorthand for all that looping and mucking about. It's not really like the Unix
grep
command; it doesn't have options to return line numbers or to negate the test, and it isn't limited to regular-expression tests. For example, to filter out just the large numbers from an array or to find out which keys in a hash have very large values:
@bigs = grep { $_ > 1_000_000 } @nums; @pigs = grep { $users{$_} > 1e7 } keys %users;
Here's something that sets
@matching
to lines from the
who
command that start with
"gnat
"
:
@matching = grep { /^gnat / } `who`;
Here's another example:
@engineers = grep { $_->position() eq 'Engineer' } @employees;
It extracts only those objects from the array
@employees
whose
position()
method returns the string
Engineer
.
You could have even more complex tests in a
grep
:
@secondary_assistance = grep { $_->income >= 26_000 && $_->income < 30_000 } @applicants;
But at that point you may decide it would be more legible to write a proper loop instead.
The "For Loops," "Foreach Loops," and "Loop Control" sections of
perlsyn
(1) and
Chapter 2
of
Programming Perl
; the
grep
function in
perlfunc
(1) and
Chapter 3
of
Programming Perl
; your system's
who
(1) manpage, if it exists;
Recipe 4.12