Как использовать getopt с нулевым дескриптором файла (‹›) в Perl?

У меня есть скрипт, который выполняет некоторые базовые функции awk, такие как фильтрация с использованием цикла while(<>). Я хочу, чтобы скрипт мог отображать использование и версию, но в противном случае предполагается, что все аргументы являются файлами. Как совместить getopt с оператором ‹>?


person brianegge    schedule 14.08.2013    source источник


Ответы (3)


Как уже упоминалось, Getopt::Long является предпочтительным модулем. Он существует со времен Perl 3.x.

Есть много параметров, и может потребоваться некоторое время, чтобы привыкнуть к синтаксису, но он делает именно то, что вам нужно:

use strict;
use warnings;
use Getopt::Long;
use feature qw(say);
use Pod::Usage;

my ( $version, $help );   #Strict, we have to predeclare these:

GetOptions(
   'help'    => \$help,
   'version' => \$version,
) or pod2usage ( -message => "Invalid options" );

Вот и все. Когда подпрограмма Getoptions запускается, она анализирует вашу командную строку (массив @ARGV) на наличие всего, что начинается с - или --. Он обработает их, и когда дело доходит до двойного тире или опции, не начинающейся с тире, он будет считать, что это файлы, и обработка завершена. В этот момент все строки опций (и их параметры) были смещены из массива @ARGSV, и вы остались со своими файлами:

if ( $help ) {
    pod2usage;
}
if ( $version ) {
    say "Version 1.23.3";
    exit;
}

while ( my $file = <>) {
    ...
}

Getopts::Long является частью стандартной установки Perl, поэтому он всегда должен быть доступен для вас.

Я знаю, что многие с осторожностью относятся к этим модулям, потому что думают, что они не являются стандартным Perl, но являются такой же частью Perl, как и такие команды, как print и chomp. Perl поставляется с более чем 500 из них, и вы можете их использовать.

person David W.    schedule 14.08.2013
comment
На самом деле есть несколько модулей, которые не поставляются с Perl, и я бы назвал их стандартными Perl. Одним из примеров является LWP. - person Brad Gilbert; 17.08.2013
comment
Есть определенные модули, которые я хотел бы видеть включенными в стандартную установку Perl: LWP, Readonly, Net::LDAP и некоторые модули JSON и XML. Я делаю много скриптов на серверах под контролем других. Установка любого дополнительного модуля CPAN — это проблема. Серверы в моей нынешней компании работают на Perl 5.8.9. Я даже не могу использовать say или autodie. К счастью, Getopts::Long включен. - person David W.; 17.08.2013

Getopt прекрасно сочетается с @ARGV. Пример

use strict; use warnings;
use feature 'say';
use Getopt::Long;

GetOptions 'foo=s' => \my $foo;

say "foo=$foo";
say "ARGV:";
say for @ARGV;

Затем:

$ perl test.pl --foo fooval --bar
Unknown option: bar
foo=fooval
ARGV:
$ perl test.pl --foo fooval bar
foo=fooval
ARGV:
bar
$ perl test.pl --foo fooval -- --bar
foo=fooval
ARGV:
--bar

Резюме:

  • Любые элементы в @ARGV после переключателей просто остаются там.
  • Это работает, как и ожидалось, для обычных имен файлов (которые не начинаются с дефиса-минус).
  • Вы всегда можете использовать --, чтобы прервать синтаксический анализ переключателей.
person amon    schedule 14.08.2013

Это работает, как и ожидалось для меня.

use warnings;
use strict;
use Getopt::Long qw(GetOptions);

my %opt;
GetOptions(\%opt, qw(help)) or die;

die 'usage' if $opt{help};

while (<>) {
    print;
}
person toolic    schedule 14.08.2013