1

Hi I wanted to implement both command line argument1, and either piped STDIN (through lone single dash '-') or a filename as argument2, using Getop::Long in Perl. In perldoc it is merely mentioned a little bit "A lone dash on the command line will now be a legal option, and using it will set variable $stdio": (https://perldoc.perl.org/Getopt/Long.html). But this is far from what I can use. I tried the following

#!/usr/bin/perl -w
use strict;
use Getopt::Long;
my ($se, $st);
GetOptions("se=s" => \$s, '' => \$st) or die "Usage: $0 -s <tab|space|comma>\n";
$st = <STDIN>;
print "$se\n$st\n";

However $st only returns the first line or should I use a filehandle? Then what if the lone single dash '-' is not there and a filename is specified as argument2? Thanks a lot,

Yiran Guo
  • 9
  • 2
  • Can you show examples of usage you need? When you set up an option `--o` (for example) with Getopt, both `script.pl -o val file` and `echo "..." | script.pl -o val` will read in the option value and you'll be able to read either from the pipe or the file with `while (<>)`. (Is that not what you want?) – zdim Dec 12 '18 at 18:24
  • @zdim It is something like `script.pl -s tab filename` or `head -3 filename | script.pl -s tab -` – Yiran Guo Dec 12 '18 at 20:37
  • Then that should work exactly as in my comment (see @ikegami answer). Note that you do not need the `-` for what you want. – zdim Dec 12 '18 at 20:48
  • Aha yes thanks a lot @zdim – Yiran Guo Dec 12 '18 at 21:05

1 Answers1

2

Just use <> (short for <ARGV>) instead of <STDIN>. ARGV is a special handle that reads from STDIN if @ARGV is empty, and reads from the each of the files specified in @ARGV if it's not.

GetOptions("se=s" => \my $se)
   or die "Usage: $0 -s <tab|space|comma>\n";

my $st = <>;
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • I tried <> instead of and it is the same - only the first row is printed. What I want is something like `script.pl -s tab filename` or `head -3 filename | script.pl -s tab -` – Yiran Guo Dec 12 '18 at 20:38
  • @YiranGuo The answer shows you the principle, the main point being to use `<>` (without `STDIN`). In order to read more use `while (<>) { ... }` instead of reading it into a scalar variable. (Or, you can read it into an array, which will then fetch all lines, but I'd recommend to use a `while` instead.) – zdim Dec 12 '18 at 21:07