Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Detecting last line and blank line

by Anonymous Monk
on Nov 07, 2017 at 00:03 UTC ( #1202892=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Say you are reading in some date line by line, is it possible to do an if command that that looks if it's the last line?

if ($data = Last line){ print "This is the last line\n"; }

And a similar if it's a blankline (containing 0 characters). But I feel that's more easy.

Replies are listed 'Best First'.
Re: Detecting last line and blank line
by davido (Cardinal) on Nov 07, 2017 at 01:04 UTC

    The eof operator is useful here.

    #!/usr/bin/env perl use strict; use warnings; my $fh = \*DATA; while(<$fh>) { chomp; print "<<<$_>>> is line $."; print ", and is the last line." if eof($fh); } continue { print ".\n"; } __DATA__ line 1 line 2 line 3

    This produces the following output:

    <<<line 1>>> is line 1. <<<line 2>>> is line 2. <<<line 3>>> is line 3, and is the last line.

    My purpose in copying \*DATA into $fh was just so that the remainder of my example could operate on a filehandle that is closer to what one might see in typical code.


    Dave

      Anonymous Monk: eof is indeed useful, and just to add two points to what davido wrote, there are two peculiarities when it is used in while (<>) loops, including the implicit ones from the -n and -p command line switches. First, eof with and without empty parentheses is different - from its docs:

      In a while (<>) loop, eof or eof(ARGV) can be used to detect the end of each file, whereas eof() will detect the end of the very last file only.

      Second, davido's code example uses the line counter $., which does not get reset for each file in a while (<>) loop. To do that, you need close ARGV explicitly, that is:

      while (<>) { # your code here } continue { close ARGV if eof; # Not eof()! }

      This is normally done in a continue block because that way, it will still be executed even if you use next inside the loop.

      As for blank lines, I like to use next unless /\S/; to skip lines that contain only whitespace. That doesn't exactly meet your "0 characters" requirement - as LanX said, use eq to compare the line to "" after chomp (or to "\n" before).

      Although you don't say why you need to detect blank lines and the last line, note that setting $/=""; means files will be read in "paragraph mode", that is, records will be separated by one or more blank lines.

Re: Detecting last line and blank line
by 1nickt (Monsignor) on Nov 07, 2017 at 00:40 UTC

    If you know the number of lines, e.g if you get an array on standard input, or passed to a subroutine:

    use strict; use warnings; use feature qw/ say /; chomp( my @lines = (<DATA>) ); my $num = @lines; my $count = 1; for my $line ( @lines ) { say "the last line is $line" if $num == $count++; } __DATA__ foo bar baz qux
    $ perl 1202892.pl the last line is qux

    If you don't know the number of lines, e.g. when reading a file that may be too large to slurp into memory all at once:

    use strict; use warnings; use feature qw/ say /; # setting up the demo use Path::Tiny; my $file = Path::Tiny->tempfile; $file->spew("$_\n") for ('a' .. 'm'); ####### my $last_line; open my $fh, '<', $file or die "Cannot open file: $!"; while ( my $line = <$fh> ) { chomp $line; $last_line = $line; } say "the last line is $last_line"; __END__
    $ perl 1202892-2.pl the last line is m

    Hope this helps!


    The way forward always starts with a minimal test.

      I figured it out, before I saw you answer!

      But thanks anyway ;-) !

      (Ended up doing something similar to your last code)

Re: Detecting last line and blank line
by LanX (Bishop) on Nov 07, 2017 at 01:14 UTC
    See eof for last line.

    An empty line means $line eq "" after chomp $line

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

    A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1202892]
Approved by beech
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (2)
As of 2018-09-20 03:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Eventually, "covfefe" will come to mean:













    Results (171 votes). Check out past polls.

    Notices?
    • (Sep 10, 2018 at 22:53 UTC) Welcome new users!