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

How can i skip the last line in a flatfile, which is like so:
"ZYZYGY3",16-AUG-2002" done,3485
where 'done' is the first thing on the line...
I have tried the following and it reads the line unless i add an extra return..i have added (\n) to show formatting marks
while (<PAST>) { next until $. > 1; $contents[$co] = $_; next if $_ = /^done/; next if m/^\s+$/; $co++; }
"ZYZYGY1",16-AUG-2002"(\n) "ZYZYGY2",16-AUG-2002"(\n) "ZYZYGY3",16-AUG-2002"(\n) done,3485(\n)

but works and removes the last lines in this example when i add an extra return after 'done'...
"ZYZYGY1",16-AUG-2002"(\n) "ZYZYGY2",16-AUG-2002"(\n) "ZYZYGY3",16-AUG-2002"(\n) done,3485(\n) (\n)

the error gives me "Use of uninitialized value in string...." if i do not get rid of this last line in a foreach loop... tks monks!

Replies are listed 'Best First'.
Re: term in last line of flatfile
by demerphq (Chancellor) on Oct 10, 2002 at 16:55 UTC
    I presume you want to skip the first line right? Thats what the
    next until $. >1;
    is supposed to do? Except it doesnt. :-) until != unless. Also it isnt the best way to remove the first line, as it puts a conditional inside a loop that need not be.

    Then you have a problem with

    next if $_ = /^done/;
    which is exactly equivelent to
    next if $_= $_=~/^done/;
    Which isnt what you want at all. In addition I question whether that should really be last and not next. So I would say it should be
    last if /^done/; #or #last if $_=~/^done/;
    But by the time I get to this point I reckon that you are trying to put all but the first and the (ostensibly) last record in the file into an array, skipping blank lines. If so I would write it as
    my @contents; my $header=<PAST>; # extract the first line while (<PAST>) { next unless /\S/; # ignore whitespace only lines. last if /^done/; # finish when we hit a line starting with 'done +' #chomp; # uncomment if you dont want newlines in conten +ts. push @contents,$_; # add the line to the buffer }
    UPDATE:

    Assuming that the done line also contains a count then you may want to check that it matches with

    my @contents; my $header=<PAST>; # extract the first line while (<PAST>) { next unless /\S/; # ignore whitespace only lines. if (/^done,(\d+)$/) { die "Count mismatch in trailer. Got $1 expected @{[scalar @con +tents]}" unless $1 == scalar(@contents); last; } #chomp; # uncomment if you dont want newlines in conten +ts. push @contents,$_; # add the line to the buffer }
    HTH

    --- demerphq
    my friends call me, usually because I'm late....

      Great! that handles it perfectly, no errors at all.. thank you very much indeed... you are most kind, you were quite right i did have a header also! cheers!
Re: term in last line of flatfile
by kabel (Chaplain) on Oct 10, 2002 at 16:42 UTC
    the "matching" operator is =~, not =
    and matching against $_ can save you a few chars:
    next if (/^done/);
Re: term in last line of flatfile
by admiraln (Acolyte) on Oct 10, 2002 at 16:45 UTC
    You could reverse your test and match only what you are looking for : a quoted string , a comma, and a date.

    this would exclude all lines that don't match anywhere not just at the end. This is a "Good Idea" because the list of thing you don't what could be infinite and the things you do want should be very short.

Re: term in last line of flatfile
by blakem (Monsignor) on Oct 10, 2002 at 22:57 UTC
    How can i skip the last line in a flatfile
    You could use eof() like this:
    while(<PAST>) { last if eof(PAST); ... }

    -Blake