5

When running perl -n or perl -p, each command line argument is taken as a file to be opened and processed line by line. If you want to pass command line switches to that script, how can I do that?

mpersico
  • 766
  • 7
  • 19
  • 1
    In a `BEGIN` block. Normally you'd use `Getopt::Std` or `Getopt::Long`. There's also perl's `-s` option. – Shawn Nov 28 '18 at 17:46

2 Answers2

8

There are three primary ways of passing information to Perl without using STDIN or external storage.

  • Arguments

    When using -n or -p, extract the arguments in the BEGIN block.

      perl -ne'BEGIN { ($x,$y)=splice(@ARGV,0,2) } f($x,$y)' -- "$x" "$y" ...
    
  • Command-line options

    In a full program, you'd use Getopt::Long, but perl -s will do fine here.

      perl -sne'f($x,$y)' -- -x="$x" -y="$y" -- ...
    
  • Environment variables

      X="$x" Y="$y" perl -ne'f($ENV{X},$ENV{Y})' -- ...
    
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • And now I see why I was having such a hard time. Check this out: `perl -ne 'BEGIN{some; code; that; checks for -n;} per; line; code;' -n file1 file2` See my mistake? I unconsciously assumed that once I Perl processed the -e, all other args were for my program. Not so: that -n was swallowed by Perl. And, technically, so are the filenames. From your second paragraph, it hit me that I had to add -- to stop option processing by Perl. Then I can process ARGV to my heart's content in the BEGIN block and anything left will be left to -p or-n handling. Thank you @ikegami – mpersico Nov 30 '18 at 14:26
0

Here is a short example program (name it t.pl), how you can do it:

#!/bin/perl
use Getopt::Std;

BEGIN {
  my %opts;
  getopts('p', \%opts);
  $prefix = defined($opts{'p'}) ? 'prefix -> ' : '';
}

print $prefix, $_;

Call it like that:

perl -n t.pl file1 file2 file3

or (will add a prefix to every line):

perl -n t.pl -p file1 file2 file3
Donat
  • 4,157
  • 3
  • 11
  • 26
  • 1
    There really is no case where new code should use ::Std. Always start with Getopt::Long – ysth Nov 28 '18 at 20:24
  • Yes, using long options is more up to date. You can easily adapt and improve. This is only for demonstration. – Donat Nov 28 '18 at 20:51
  • 1
    even just using short options, you should use Getopt::Long; it's no more difficult. – ysth Nov 28 '18 at 22:12