Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Reading two lines per loop iteration

by fishnflute (Novice)
on Jun 08, 2007 at 20:04 UTC ( [id://620077]=perlquestion: print w/replies, xml ) Need Help??

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

Sorry for the confusion, it seemed like everyone was close answering but I'm not sure. Currently the data looks like: GSF : "495,916" Electricity RenElec Demand Steam Gas RenGas Oil Coal Chill. Wtr (KWH) (KWH) (KW) (MLB) (Cubic Ft) (Cubic Ft) (Gallon) (Ton) (Ton Hr) Oct Usage "316,800 A" 0 0 0 "375,487 A" 0 0 0 0 Cost "$53,671 A" $0 $0 $0 "$5,799 A" $0 $0 $0 $0 Nov Usage "331,200 A" 0 0 0 "719,832 N" 0 0 0 0 Cost "$35,511 N" $0 $0 $0 "$11,542 N" $0 $0 $0 $0 I currently am lacking a code other than what I would use to rearrange variables and load to MySQL. I want Perl to take the line of Cost which is associated with the Month of Usage above it. Is there any way Perl can read both lines at a time to allow me to play with the variables?

Replies are listed 'Best First'.
Re: Reading two lines per loop iteration
by FunkyMonk (Chancellor) on Jun 08, 2007 at 20:13 UTC
    This sort of thing?

    while ( my $line1 = <$fh> ) { my $line2 = <$fh>; # etc }

    You'll need to check for eof on the second read though.

      This sort of thing?

      while ( my $line1 = <$fh> ) { my $line2 = <$fh>; # etc }

      Except that

      while ( my $line1 = <$fh> )

      is just the same as

      while ( defined(my $line1 = <$fh>) )

      so perhaps I would do:

      while ( my $line1 = <$fh> ) { defined(my $line2 = <$fh>) or last; # etc }
Re: Reading two lines per loop iteration
by BrowserUk (Patriarch) on Jun 09, 2007 at 04:39 UTC

    Why not just read both lines at a time? It even seems to handle the case of the file ending with an odd line correctly.

    #! perl -slw use strict; while( my $line = <DATA> . <DATA> ) { print "'$line'"; } __DATA__ 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 an odd record

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Reading two lines per loop iteration
by ikegami (Patriarch) on Jun 09, 2007 at 03:34 UTC
    for (;;) { my $line1 = <$fh>; last if not defined $line1; my $line2 = <$fh>; last if not defined $line2; ... }
Re: Reading two lines per loop iteration
by GrandFather (Saint) on Jun 08, 2007 at 20:18 UTC

    Please show us a little code. Read I know what I mean. Why don't you? then post about a dozen lines of code and data demonstrating your problem and tell us what you get and what you want. We don't want to see the database code, just a few line pertinent to showing the issue you have parsing the data and a few lines of sample data.


    DWIM is Perl's answer to Gödel
Re: Reading two lines per loop iteration
by ww (Archbishop) on Jun 08, 2007 at 20:54 UTC

    sounds like an XY problem to me. Why not something like this <pseudocode>?
    Update After I finished writing this, I discovered FunkyMonk had already hit on essentially the same plan. ++, FunkyMonk

    # Get the data into an array, or grab it a line at a time; # Read a line/array element to a var, $input; # ie, up to the first + return $may_be_a_full_entry_or_may_not = $input; Loop and read the next line to $input; use a regex to see if it starts with "day\t" if (it matches) { STORE $may_be_a_full_entry_or_may_not; s/"blank"//; # or use a capturing regex # whatever that is: tab, space, multi-spaces??? # be careful to make only the first "blank" go a +way! STORE $input; } else { s/"blank"//; # or use a capturing regex $input = $may_be_a_full_entry_or_may_not; . $input; # concat the +two lines STORE $input to your db; }

    repeating until done.

    The details of the loop are left to you. Note, this is a) in-elegant and b) won't work, obviously, if the data entry folk spread their daily report over 3 lines.

    Update2 Fixed formatting. Thank you, injunjoel!

Re: Reading two lines per loop iteration
by varian (Chaplain) on Jun 09, 2007 at 07:39 UTC
    Perl's flipflop operator is very useful for such requirements. This tutorial by Grandfather is an excellent primer.

    The example code below allows for an arbitrary number of lines with an empty 'day' field, it reuses the last non-empty day field read.

    #!/usr/bin/perl use strict;use warnings; my $day = ''; while (my $line = <DATA>) { chomp $line; my ($newday,$ptime,$stime,$ctime,$amount) = split /\t/,$line; $day = $newday if $newday..$newday; print "$day\t$ptime\t$stime\t$ctime\t$amount\n"; } __DATA__ 01-May-2007 34 11am 567 665 65 12am 657 4 64 4pm 345 3 05-May-2007 87 10pm 987 56 06-May-2007 987 9am 8899 765 567 unkn 4 3
    This prints:
    01-May-2007 34 11am 567 665 01-May-2007 65 12am 657 4 01-May-2007 64 4pm 345 3 05-May-2007 87 10pm 987 56 06-May-2007 987 9am 8899 765 06-May-2007 567 unkn 4 3
Re: Reading two lines per loop iteration
by tirwhan (Abbot) on Jun 09, 2007 at 13:47 UTC

    Good solutions above, this is how you could do it in Perl 6:

    my $fh = open("file"); for =$fh->$line1,$line2 { # do whatever with the two lines }

    All dogma is stupid.

      I've been trying to do this in perl6, I can get your solution to work - perl6 may well have changed in the meantime.

      In fact I get an error message about the =$
      ... Preceding context expects a term, but found infix = instead. Did you make a mistake in Pod syntax? ... ------> for =^$fh -> $line1, $line2 {
      I had thought that something like this might work:
      my $fh = open("file"); for $fh.lines,$fh.lines -> $line1,$line2 { say $line1; say $line2; }
      but this seems to produce a rather confusing result with all the lines stuck together is a Seq, and has some EOF related error, the 'singluar form':
      for $fh.lines -> $line { say $line; }

      works fine.

      What is true is already so. Owning up to it doesn't make it worse. - Eugene Gendlin
Re: Reading two lines per loop iteration
by mattr (Curate) on Jun 09, 2007 at 13:15 UTC
    Are you saying there are a lot of cost_time lines all together? If it's just one (i.e. they come in Day/cost_time pairs) then a simple string replacement would solve the problem. Otherwise just remember the content of the last Day line and insert the data into any subsequent ones that don't start with Day.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2024-03-19 04:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found