Как анализировать аргументы в кавычках, а также аргументы без кавычек в Perl?

#perl #command-line

#perl #командная строка

Вопрос:

Я хочу, чтобы мой perl-скрипт правильно разбирал два аргумента командной строки, разделенных пробелом, на две переменные:

 $ cat 1.pl
print "arg1 = >$ARGV[0]<n";
print "arg2 = >$ARGV[1]<n";
$ perl 1.pl a b
arg1 = >a<
arg2 = >b<
$ perl 1.pl "a b"
arg1 = >a b<
arg2 = ><
$
  

Есть ли общий способ справиться с этим, а не пытаться определить, использовались кавычки или нет?

Комментарии:

1. Вы хотите p3rl.org/Getopt::Long#Options_with_multiple_values , таким образом: program --foo arg1 --foo arg2 .

Ответ №1:

Данные передаются в Perl командной оболочкой.

  • program a b отправит a и b
  • program 'a b' отправит a b
  • program "a b" отправит a b
  • program a b отправит a b

Perl, AFAIK, не имеет способа определить разницу между любыми из последних трех.

Вы могли бы split использовать для каждого аргумента пробелы, и это дало бы описываемый вами эффект … но это означало бы, что работа отличается от работы любого другого приложения.

Комментарии:

1. Точно; если пользователь явно заключил аргумент в кавычки, это не «два аргумента командной строки», это один. Если рассматривать это как два, ваши пользователи возненавидят вас.

2. Итак, мне нужно проверить, был передан один аргумент или два (код ожидает два). Если был передан один аргумент, я разделю его на два, это правильно?

3. Ты мог бы это сделать. Я бы отправил пользователю отчет об ошибке и вместо этого отобразил информацию об использовании.

4. die "Two arguments are required" unless @ARGV == 2 ; КСТАТИ: выясняя, является ли что-то аргументом или нет, я не могу не думать о Монти Пайтоне youtube.com/watch?v=teMlv3ripSM

Ответ №2:

Ответ Квентина не совсем подходит для Windows.

Между тем, если вы хотите проанализировать переключатели, Getopt::Long лучше всего подходит для этого. Но если у вас есть два аргумента, не являющихся переключателями, вы могли бы попробовать этот метод грубой силы:

 my @args = map { split ' ' } @ARGV;
die usage() unless @args == 2; 
  

или это:

 die usage() 
    unless (
    my ( $arg1, $arg2 )
        = @ARGV == 1 ? ( split ' ', $ARGV[0], 3 )
        : @ARGV == 2 ? @ARGV
        :              ()
    ) == 2
    ;
  

Здесь die usage() просто псевдокод.