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

I have two files; in file 1 I am reading line by line, in file 2 I am changing the delimiter using local ($/) ="" to read one paragraph at a time.

The following is shortened version of what I am trying to do

$old_pos = 0 while ($A = <FILE1>) ($tmp,$pos)= split /\s+/, $A; open(FILE2,"<$file2name") or die "cant open $file2name for reading! +\n"; local($/) = ""; seek FILE2, $old_pos, 0; while (<FILE2>){ @lines = split(/\n/,$_); ($posB,$posend) = findpos(@lines); next if $posA < $posB; last if $posA > $posB + $posend; processPara(@lines) } } $old_pos = tell FILE2; }
Basically, instead of opening FILE 2 from the start for every line in file 1, I want to open from the position I was at last time I opened the file. However, based on the time it is taking I dont think it is working. I print out the line number of the first file every 50 lines - the first 50 fly then after that it slows down a lot. Is there something I am not doing correctly, especially with changing the delimiter?

Kind thanks!

Replies are listed 'Best First'.
Re: seek /tell changing input delimiter
by ikegami (Patriarch) on Mar 10, 2009 at 02:49 UTC
    I don't see why you need seek and tell at all.
    open(FILE2,"<$file2name") or die "cant open $file2name for reading!\n" +; while ($A = <FILE1>) ($tmp,$pos)= split /\s+/, $A; local($/) = ""; while (<FILE2>){ @lines = split(/\n/,$_); ($posB,$posend) = findpos(@lines); next if $posA < $posB; last if $posA > $posB + $posend; processPara(@lines) } } }

    Well, that's assuming the tell isn't really outside the while as it was in your code. And you never set $posA.

    With those errors fixed, with the scoping errors fixed, with strict and warnings not disabled, with a better error message for open, and with proper indenting, we get:

    use strict; use warnings; open(my $fh2, '<', $file2name) or die("Can't open $file2name for reading: $!\n"); while (<$fh1>) my (undef, $posA) = split(/\s+/); local $/ = ""; while (<$fh2>){ my @lines = split(/\n/); my ($posB, $posend) = findpos(@lines); next if $posA < $posB; last if $posA > $posB + $posend; processPara(@lines); } }