Re: Reading two lines per loop iteration
by FunkyMonk (Chancellor) on Jun 08, 2007 at 20:13 UTC
|
while ( my $line1 = <$fh> )
{
my $line2 = <$fh>;
# etc
}
You'll need to check for eof on the second read though. | [reply] [Watch: Dir/Any] [d/l] |
|
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
}
| [reply] [Watch: Dir/Any] [d/l] [select] |
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.
| [reply] [Watch: Dir/Any] [d/l] |
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;
...
}
| [reply] [Watch: Dir/Any] [d/l] |
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
| [reply] [Watch: Dir/Any] |
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!
| [reply] [Watch: Dir/Any] [d/l] |
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
| [reply] [Watch: Dir/Any] [d/l] [select] |
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
}
| [reply] [Watch: Dir/Any] [d/l] |
|
...
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
| [reply] [Watch: Dir/Any] [d/l] [select] |
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. | [reply] [Watch: Dir/Any] |