5

Perl スクリプトに次のコードがあります。

私の$ディレクトリ;
私の@ファイル;
私の $help;
私の $man;
私の $verbose;

undef $ディレクトリ;
undef @files;
undef $help;
undef $man;
undef $verbose;

GetOptions(
           "dir=s" => \$directory, # デフォルト値を持つオプションの変数 (false)
           "files=s" => \@files, # コンマ区切りを許可するオプションの変数
                                # ファイル名のリストと複数
                    # このオプションの出現。
           「助けて|?」=> \$help, # デフォルト値を持つオプションの変数 (false)
           "man" => \$man, # デフォルト値を持つオプションの変数 (false)
           "verbose" => \$verbose # デフォルト値を持つオプションの変数 (false)
          );

    if (@ファイル) {
    @files = split(/,/,join(',', @files));
    }

相互に排他的なコマンド ライン引数を処理する最良の方法は何ですか? 私のスクリプトでは、ユーザーに「--dir」または「--files」コマンドライン引数のみを入力させ、両方を入力させないようにしています。これを行うためにGetoptを構成する方法はありますか?

ありがとう。

4

5 に答える 5

4

Getopt::Long でそれを行う方法はないと思いますが、自分で実装するのは簡単です (ユーザーにプログラムの呼び出し方法を伝える文字列を返す使用関数があると想定しています)。 ):

die usage() if defined $directory and @files;
于 2009-05-20T16:21:09.853 に答える
3

なぜこれだけではないのですか:

if ($directory && @files) {
  die "dir and files options are mutually exclusive\n";
}
于 2009-05-20T16:24:04.623 に答える
2

両方の変数に値が存在するかどうかを簡単に確認できます。

if(@files && defined $directory) {
    print STDERR "You must use either --dir or --files, but not both.\n";
    exit 1;
}

または、最初の --dir または --files の後に指定されたオプションを単純に無視したい場合は、両方を関数に指定できます。

#!/usr/bin/perl

use Getopt::Long;

my $directory;
my @files;
my $mode;
my $help;
my $man;
my $verbose; 

GetOptions(
    "dir=s" => \&entries,    # optional variable with default value (false)
    "files=s" => \&entries,  # optional variable that allows comma-separated
                             # list of file names as well as multiple 
                             # occurrences of this option.
    "help|?" => \$help,      # optional variable with default value (false)
    "man" => \$man,          # optional variable with default value (false)
    "verbose" => \$verbose   # optional variable with default value (false)
);

sub entries {

   my($option, $value) = @_;

    if(defined $mode && $mode ne $option) {
        print STDERR "Ignoring \"--$option $value\" because --$mode already specified...\n";
    }
    else {
        $mode = $option unless(defined $mode);
        if($mode eq "dir") {
            $directory = $value;
        }
        elsif($mode eq "files") {
            push @files, split(/,/, $value);
        }
    }

    return;

}

print "Working on directory $directory...\n" if($mode eq "dir");
print "Working on files:\n" . join("\n", @files) . "\n" if($mode eq "files");
于 2009-05-20T16:37:34.143 に答える
0

でこれを行うことができますGetopt::Long::Descriptive。とは少し異なりGetopt::Longますが、使用状況の概要を印刷する場合は、すべての作業を自動的に行うことで重複を減らすことができます。

ここでは、 と呼ばれる隠しオプションを追加しました。sourceこれ$opt->sourceにより、値が含まれるdirfiles、指定されたオプションに応じてone_of制約が適用されます。与えられた値は、$opt->dirまたは$opt->files与えられた方になります。

my ( $opt, $usage ) = describe_options(
    '%c %o',
    [ "source" => hidden => {
        'one_of' => [
            [ "dir=s" => "Directory" ],
            [ "files=s@" => "FilesComma-separated list of files" ],
        ]
    } ],
    [ "man" => "..." ],          # optional variable with default value (false)
    [ "verbose" => "Provide more output" ],   # optional variable with default value (false)
    [],
    [ 'help|?' => "Print usage message and exit" ],
);
print( $usage->text ), exit if ( $opt->help );

if ($opt->files) {
    @files = split(/,/,join(',', @{$opt->files}));
}

スクリプトの残りの部分との主な違いは、$optwith のように各オプションが独自の変数を持つのではなく、すべてのオプションが変数のメソッドとして含まれていることGetopt::Longです。

于 2016-09-08T18:16:43.087 に答える
0
use strict;
use warnings;
use Getopt::Long;

my($directory,@files,$help,$man,$verbose);

GetOptions(
  'dir=s'   => sub {
    my($sub_name,$str) = @_;
    $directory = $str;

    die "Specify only --dir or --files" if @files;
  },

  # optional variable that allows comma-separated
  # list of file names as well as multiple 
  # occurrences of this option.
  'files=s' => sub {
    my($sub_name,$str) = @_;
    my @s = split ',', $str;
    push @files, @s;

    die "Specify only --dir or --files" if $directory;
  },    

  "help|?"  => \$help,
  "man"     => \$man,
  "verbose" => \$verbose,
);

use Pod::Usage;
pod2usage(1) if $help;
pod2usage(-exitstatus => 0, -verbose => 2) if $man;
=head1 名前

サンプル - Getopt::Long と Pod::Usage の使用

=head1 あらすじ

サンプル [オプション] [ファイル ...]

 オプション:
   -help 簡単なヘルプ メッセージ
   -man 完全なドキュメント

=head1 オプション

=8以上

=アイテムB

簡単なヘルプ メッセージを出力して終了します。

=アイテムB

マニュアルページを印刷して終了します。

=戻る

=head1 説明

B は、指定された入力ファイルを読み取り、何かを実行します
その内容で役に立ちます。

=カット
于 2009-05-20T21:42:29.753 に答える