I would first encourage you to Use strict and warnings.
A hash would work well for this application. If you're using strict, you can declare it like so:
my %total_for;
Then you can access the elements by operator name.
my $operator = 'Nicole';
$total_for{$operator} = 123; # total for Nicole is 123
$total_for{$operator} += 45; # increase Nicole's total by 45.
You can loop over the names using keys like so:
foreach my $operator ( sort keys %total_for ) {
print "Total for $operator: $total_for{$operator}\n";
}
I also used sort here because the keys come out in no particular order.
A few other notes:
- Check that your open succeeded.
open(LOG, $file) or die "Can't read '$file': $!";
- Rather than read the whole file before you begin processing, process it a line at a time.
while (<LOG>) {
@tmpwords = split;
# etc.
}
- If you're reading a line at a time like that, you'll want to chomp your incoming data. (Your code as-is takes care of this with split.)
- In general, it's a good idea to name your loop variables instead of using $_ everywhere.
foreach my $blah ( @array ) {
# use $blah instead of $_ for things
}
- When you interpolate a variable into a regular expression as in "grep /@tmpwords[1]/, @operators", any regexp metacharacters get interpreted as metacharacters. You can avoid this by using \Q like so: /\Q@tmpwords[1]\E/. In your case, this doesn't make a difference because there aren't any metacharacters in your data file. One problem you might have, however, is that an operator named "Jen" would "match" another operator named "Jennifer" because the pattern is not anchored at the ends. In general, if you're looking for an exact match, you should say something like "grep $_ eq @tmpwords[1], @operators".
Update: Since others have posted full working solutions now, I might as well also (I was trying to treat this as a student).
use strict;
use warnings;
my $file = 'msgcount.txt';
open my $fh, '<', $file
or die "Can't read '$file': $!";
my %total_for;
while ( <$fh> ) {
my $line = $_;
chomp;
s{ \A \d\d / \d\d / \d{4} \s+ }{}xms
or die "line does not match: $line";
my ( $name, $numb ) = m{ \A ( .+ ) \s+ ( \d+ ) \s* \z }xms;
if ( ! $name ) {
die "line does not match: $line";
}
$total_for{ $name } += $numb;
}
close $fh or die "Failed to close: $!";
foreach my $operator ( sort keys %total_for ) {
print "Total for '$operator': $total_for{$operator}\n";
}
This accounts for the suggestion from mr_mischief (in case names are not all non-spaces). It will die if it hits a line outside the format it expects. I haven't run it.
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.