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

I have a dat file looking like this:

Running totals: Question 1: 60 Question 2: 123 Question 3: 99 Averages: Question 1: 4.6 Question 2: 9.5 Question 3: 7.6

I have a code to store the Running totals into a hash, such as the following:

my %hash; my $key; my $value; open(ANSWERTALLY, "answertally.dat"); while(ANSWERTALLY n) { ($key, $value) = split(/\s=\s/); chomp($value); $hash{$key} = $value; } close(ANSWERTALLY);

However, this code will try to read everything in the file. How can I tell it to skip the first line (RUNNING TOTALS), and stop executing when it encounters AVERAGES:??? I'm not too good with string manipulation or regular expressions.

Thanks

Replies are listed 'Best First'.
Re: reading from middle of file
by davorg (Chancellor) on Aug 12, 2004 at 15:25 UTC
    my %hash; open(ANSWERTALLY, "answertally.dat"); while(<ANSWERTALLY>) { next unless /^Running totals:/ .. /^Averages:/; next if /^Running totals:/; last if /^Averages:/; my ($key, $value) = split(/\s=\s/); chomp($value); $hash{$key} = $value; } close(ANSWERTALLY);
    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      Thank you, it has worked!! I only have two more questions.

      Question 1:
      First, if I'm printing a string and the value of a calculation of 2 variables, as in:

      print "The average is $total/$count";
      ...how can I do it so that the value of the calculation shows up?? Right now I'm getting something like:
      The average is 60/9
      Do I have to use PRINTF??? In fact, while we're on this subject, how can I format the value so that it only has two decimal places?

      Question 2:
      What are these NEXT, UNLESS and LAST statements? In my whooping 1 week of PERL, I haven't yet come across these statements. I'd like to learn. Can you suggest a good place for looking up PERL syntax/statements?

      Thanks a bunch

        Question 1:
        First, if I'm printing a string and the value of a calculation of 2 variables, as in:
        print "The average is $total/$count";
        ...how can I do it so that the value of the calculation shows up?? Right now I'm getting something like:
        The average is 60/9

        Just take the calculation out of the quoted string.

        print "The average is ", $total/$count;
        Do I have to use PRINTF??? In fact, while we're on this subject, how can I format the value so that it only has two decimal places?

        That you can do with printf.

        printf "The average is %.2f", $total/$count;
        Question 2:
        What are these NEXT, UNLESS and LAST statements? In my whooping 1 week of PERL, I haven't yet come across these statements. I'd like to learn. Can you suggest a good place for looking up PERL syntax/statements?

        Type perldoc perltoc at your command line to see the table of contents for the Perl documentation. For the loop control statements, see the "Loop control" section in perldoc perlsyn.

        --
        <http://www.dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

        print "The average is " . $total/$count . "\n";

        -or a little more fun-

        print "The average is @{[$total/$count]}\n";

        but as you say this is floating point output so printf it:

        printf ("The average is %2.2f",  $total/$count)

        Cheers,
        R.

Re: reading from middle of file
by Dietz (Curate) on Aug 12, 2004 at 16:36 UTC
    Beware!
    split(/\s=\s/) will not do what you think it should.

    Try this one:

    #!/usr/bin/perl use strict; use warnings; my %hash; open(ANSWERTALLY, "answertally.dat"); while(<ANSWERTALLY>) { next unless /^Running totals:/ .. /^Averages:/; # by davorg next if /^$/; # next line if empty next if /^Running totals:/; # by davorg last if /^Averages:/; # by davorg my ($key, $value) = split(/:/); # you actually just want to split by + ':' $value =~ s/\s*//g; # remove whitespace globally $hash{$key} = $value unless $value eq ""; # add to hash only if valu +e is holding data } close(ANSWERTALLY); for my $key(sort keys %hash) { print "\$key: $key\t\$hash{\$key}: $hash{$key}\n"; } __END__ __OUTPUT__ $key: Question 1 $hash{$key}: 60 $key: Question 2 $hash{$key}: 123 $key: Question 3 $hash{$key}: 99