Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re^3: Regex match on implicit default variable ($_) in a script, not a one liner

by GotToBTru (Prior)
on Oct 24, 2015 at 03:56 UTC ( [id://1145829]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Regex match on implicit default variable ($_) in a script, not a one liner
in thread Regex match on implicit default variable ($_) in a script, not a one liner

You aren't aware of what the switches on your one-liner are doing for you. See perlrun

The -n is the most important one. It applies a while(<>) { ... } loop around your code. So, it is taking your input string, splitting it into lines, assigning each value in turn to $_, and then executing the body of your one-liner for each value. In a program, you have to specify that.

#!/usr/bin/perl use strict; use warnings; use diagnostics; my $A="abc\ndef\nghi\n"; my @list = split /\n/,$A; while (<@list>) { ! /def/ and print }

Updated: my most literal attempt didn't work, putting the split inside the while condition. So I use split to create an array. That works better.

Dum Spiro Spero
  • Comment on Re^3: Regex match on implicit default variable ($_) in a script, not a one liner
  • Download Code

Replies are listed 'Best First'.
Re^4: Regex match on implicit default variable ($_) in a script, not a one liner
by Todd Chester (Scribe) on Oct 24, 2015 at 20:15 UTC

    </quote>You aren't aware of what the switches on your one-liner are doing for you. See perlrun
    The -n is the most important one. It applies a while(<>) { ... } loop around your code.
    </quote>

    You are correct. I am confused as all get out. I think what is getting me the worst is all the short hand and defaults. For instance, is "<>" short hand for "<STDIN>"?.
    What would really help me is if you would rewrite

    echo -e "abc\ndef\nghi\n" | perl -wlne '! /def/ and print "$_";'

    for me with "-we" in place of "-wple" with all the short hand and defaults removed so I could see exactly what is going on. (You would be my hero as I have asked this elsewhere and have not understood it there either. Mostly very helpful folks show me a better way to write it in a full script. And although greatly appreciated, it does not help me understand exactly what is happening in the "-wple" one liner or how to duplicate it in a full script.)

    Many thanks, -T

      What would really help me is if you would rewrite
      echo -e "abc\ndef\nghi\n" | perl -wlne '! /def/ and print "$_";'
      for me with "-we" in place of "-wple" with all the short hand and defaults removed so I could see exactly what is going on.

      Perl does that for you, at least the part after the pipe char, if you load B::Deparse (comments mine):

      qwurx [shmem] ~> perl -MO=Deparse,-x -wlne '! /def/ and print "$_";' BEGIN { $^W = 1; } # this is -w BEGIN { $/ = "\n"; $\ = "\n"; } # this is -l LINE: while (defined($_ = <ARGV>)) { # and here is what -n does... chomp $_; # this belongs to -l print "$_" unless /def/; } # this belongs to -n too -e syntax OK

      The only line without comment is -e, i.e. your command line script body.

      Here's another example - count lines, invented by Abigail:

      perl -ne '}{ print $.'

      The }{ construct - named eskimo greeting - splits the implicit while loop into a while loop block and a bare block:

      perl -MO=Deparse,-x -ne '}{print$.' LINE: while (defined($_ = <ARGV>)) { # -n (); # script body - a noop } # script body { # script body print $.; # script body } # -n

      The bare block is used to output the current line number of the (special) filehandle ARGV.

      perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

      For instance, is "<>" short hand for "<STDIN>"?.

      <> is a very common and useful shorthand notation. You'll often encounter this, and I recommend getting familiar with it, it really comes in handy every time you want to process user-supplied input.

      The short version is that it Does What You Mean; I/O Operators has the nitty-gritty:

      The null filehandle <> is special: it can be used to emulate the behavior of sed and awk, and any other Unix filter program that takes a list of filenames, doing the same to each line of input from all of them. Input from <> comes either from standard input, or from each file listed on the command line. Here's how it works: the first time <> is evaluated, the @ARGV array is checked, and if it is empty, $ARGV[0] is set to "-", which when opened gives you standard input. The @ARGV array is then processed as a list of filenames. The loop

      while (<>) { ... # code for each line }

      is equivalent to the following Perl-like pseudo code:

      unshift(@ARGV, '-') unless @ARGV; while ($ARGV = shift) { open(ARGV, $ARGV); while (<ARGV>) { ... # code for each line } }

      except that it isn't so cumbersome to say, and will actually work. [...]

      For the various flags to the perl executable, see perlrun. -n and -p put certain loops around your code, allowing you to write only the code inside the loop (very useful for one-liners on the command line); -l auto-chomps your input, which is useful in much the same situations.

        Thank you Shmem!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1145829]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2024-04-25 23:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found