7

awk offers a convenient way to pass named variables to a script using the -v flag (e.g., awk -v var="value" ...), a facility that is quite useful when composing ad hoc scripts. Can the same be done with Perl or does one need to resort to argv, getopts, %ENV, interpolation by the shell through appropriate quoting, etc.? The -s option can give the desired effect but is limited to boolean values.

user001
  • 3,698
  • Is there a reason why you can't take it as a positional argument? – Ignacio Vazquez-Abrams Nov 08 '17 at 18:42
  • I certainly could, but was just wondering if it could be given a name. – user001 Nov 08 '17 at 18:42
  • You'll find that in general programming languages don't allow that. – Ignacio Vazquez-Abrams Nov 08 '17 at 18:44
  • Thanks, I figured it wasn't possible, but wanted to be sure. It would be convenient for one-off uses.. of course positional parameters would work as well in such a case – user001 Nov 08 '17 at 18:46
  • 4
    -s is not limited to boolean. Eg -s -xyz=abc and print $xyz\n". From the man page, perldoc perlrun. – meuh Nov 08 '17 at 18:48
  • @meuh: Thanks, I misunderstood the -s option, thinking it merely allowed setting switches. You could make your comment an answer. Could you clarify the correct use: e.g., perl -s -xyz=abc -e 'print "xyz=$xyz\n"' gives the error "No Perl script found in input" – user001 Nov 08 '17 at 19:02
  • 1
    I got the same thing too. It doesnt seem to be useful for your "oneliner" use case. You need a file with #!/usr/bin/perl -s in it for it to work! – meuh Nov 08 '17 at 19:07

2 Answers2

9

Thanks to meuh for pointing out the use of the -s option for the purpose of passing arbitrary data as opposed to simply toggling switches; after further investigation, the correct syntax for one-liner use of the -s option turned out to be the following:

$ perl -se 'print "xyz=$xyz\n"' -- -xyz="abc"
xyz=abc
user001
  • 3,698
0

The following demonstrates reading awk-like variable assignments from the command-line as well as accepting in-line perl code in a shell script:

# cat test.sh
perl - FS=':' GRP='50' <<'EOF'
eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;
print "$FS\n";
print "$GRP\n";
EOF

This is the proof:

# sh test.sh
:
50

And here is an alternative form of the OP's answer that accepts inline, multi-line perl code:

# cat test.sh
perl -s -- - -xyz="abc" <<'EOF'
print "xyz=$xyz\n";
EOF

And the proof:

# sh xyz.sh
xyz=abc

This format looks very similar to awk written in a shell script, and makes it easy to replace translated non-trivial awk code with a2p generated perl code without having to resort to putting the code in a separate file.

kbulgrien
  • 830