Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

perl -n seemingly eating a line of input

by mldvx4 (Pilgrim)
on May 01, 2017 at 11:15 UTC ( #1189251=perlquestion: print w/replies, xml ) Need Help??

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

I would expect that the following would print out all five input lines:

echo -e '55\n44\n33\n22\n11\n' | perl -n -e '@a = <>; END{ print @a; } '

Instead, the first line gets eaten. The first line always gets eaten regardless of how many numbers I send to perl.

What is the explanation for the behavior? What should be changed so that all numbers sent to perl end up in @a?

Replies are listed 'Best First'.
Re: perl -n seemingly eating a line of input
by shmem (Chancellor) on May 01, 2017 at 11:42 UTC

    This happens because at the time your loop code @a = <>; is run, there has already been an assignment to $_.

    perl -MO=Deparse -n -e '@a = <>; END{ print @a; } ' LINE: while (defined($_ = <ARGV>)) { @a = <ARGV>; sub END { print @a; } ; }

    This captures the first line also into @a:

    echo -e '55\n44\n33\n22\n11\n' | perl -n -e '@a = ($_,<>); END{ print +@a; } '
    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

      Thanks. I see the problem now, though don't see the way around it. Adding the parenthesis catches the first number, but also produces an extra line that is empty.

        ...but also produces an extra line that is empty.

        That is due to your trailing \n and has nothing to do with the parenthesized $_,<> - compare

        echo -e '55\n44\n33\n22\n11\n' | perl -n -e '@a = ($_,<>); END{ print +@a; } ' echo -e '55\n44\n33\n22\n11' | perl -n -e '@a = ($_,<>); END{ print @a +; } '

        - because echo -e will add a newline to its argument, so there are two of them, and thus an empty line. Use echo -en to suppress that:

        echo -en '55\n44\n33\n22\n11\n' | perl -n -e '@a = ($_,<>); END{ print + @a; } '
        perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
        Don't use -n, or change the way you process the lines:
        echo -e '55\n44\n33\n22\n11\n' | perl -n -e 'push @a, $_; END{ print @ +a; } '

        Explanation: -n makes perl loop through the input lines, and my code puts each line in turn onto the array. After all input is processed, I print out the array.

        If you want to do -e '@a=<>;' and get all the lines, simply don't use -n.
Re: perl -n seemingly eating a line of input
by ikegami (Patriarch) on May 01, 2017 at 15:47 UTC

    perl -n seemingly eating a line of input

    Well yeah, that's the point of -n. Specifically, -n wraps your code with

    LINE: while (<>) { ... }

    Fix (with -n):

    perl -ne'push @a, $_; END { print @a; }'

    Fix (without -n):

    perl -e'@a = <>; print @a;'
Re: perl -n seemingly eating a line of input
by Anonymous Monk on May 01, 2017 at 22:44 UTC
    TIMTOWTDI! (just move trailing newline to beginning of string) xD
    echo -e '\n55\n44\n33\n22\n11' | perl -ne'@a = <>; END{ print @a; }'

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2022-05-21 19:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (77 votes). Check out past polls.

    Notices?