Javaでコマンドライン引数を解析するにはどうすればよいですか?


586

Javaでコマンドライン引数を解析する良い方法は何ですか?


4
args4jとその使用方法の詳細な例を参照してください:martin-thoma.com/how-to-parse-command-line-arguments-in-java
Martin Thoma

私はこのパーティーにかなり遅れているように見えますが、Javaのコマンドライン引数ハンドラーを作成して、GitHub:MainArgsHandlerに配置しました。クローズされるスレッドについては、これは非常に役立つスレッドだと思いますが、一般的なプログラミングの議論のためにStack Exchange Programmersサイトに移行する必要があるかもしれません。
2014

@RedGlyph-SO / SEはルールを簡素化する必要があるようです。問題は次のとおりHow to parse java command line arguments?でした。しかし、実際にこれを行うためのコードを作成するのではなく、ツールを使用することを望んでいる人はいます。しかし、ツールなどを検索することは建設的ではありません:(
AlikElzin-kilaka '

6
再開に投票しました。@AlikElzin:実際、彼らはモデレートプロセスを確認する必要があります。非常に多くの質問を締めくくるバッジがあり、モデレーターになりたい人が熱心すぎるように誘惑しているのではないかと思います。
RedGlyph 2015

8
この質問は、不正解/一行回答とツールの推奨事項のハニーポットです。閉じたままにする必要があります。
JAL

回答:


405

これらをチェックしてください:

またはあなた自身を転がしてください:


たとえば、これはcommons-cli2つの文字列引数を解析するために使用する方法です。

import org.apache.commons.cli.*;

public class Main {


    public static void main(String[] args) throws Exception {

        Options options = new Options();

        Option input = new Option("i", "input", true, "input file path");
        input.setRequired(true);
        options.addOption(input);

        Option output = new Option("o", "output", true, "output file");
        output.setRequired(true);
        options.addOption(output);

        CommandLineParser parser = new DefaultParser();
        HelpFormatter formatter = new HelpFormatter();
        CommandLine cmd;

        try {
            cmd = parser.parse(options, args);
        } catch (ParseException e) {
            System.out.println(e.getMessage());
            formatter.printHelp("utility-name", options);

            System.exit(1);
        }

        String inputFilePath = cmd.getOptionValue("input");
        String outputFilePath = cmd.getOptionValue("output");

        System.out.println(inputFilePath);
        System.out.println(outputFilePath);

    }

}

コマンドラインからの使用法:

$> java -jar target/my-utility.jar -i asd                                                                                       
Missing required option: o

usage: utility-name
 -i,--input <arg>    input file path
 -o,--output <arg>   output file

40
他の多くのApacheライブラリとは異なり、Apache CLIには依存関係がないことに注意してください。
Vladimir Dyuzhev 2012

9
多くのapache-commonsプロジェクトの1つの欠点は、コミットが少なくなり、最終的には廃止されることです。
ブレットライアン

4
これは、Apache CLIプロジェクトの「使用シナリオ」ページで、すぐに使用を開始する方法の詳細です。commons.apache.org
Brad Parks

インターフェイスを定義し、メソッドに注釈を付ける場所を除いて、Args4J / JCommanderとまったく同じものはないと思いますか?私はプライベートフィールドを "不気味に初期化"するクラスを好きになることができませんでした...
Trejkaz

5
@RemkoPopmaあなたのピコクリライブラリーは素晴らしく見え、本当にありがとうございました。しかし、私はあなたがここや他の投稿で何をしているのか(受け入れられた回答を編集し、ライブラリをそのトップで宣伝することなく、投稿の元の作者からの編集ではなく、自分のlibであることを開示することはありません)、モデレート権限の恐ろしい恐ろしい乱用を考慮します。これを他のmodにフラグを立てます。
Alexander Malakhov

312

最近のJCommanderを見てください

作成しました。質問や機能のリクエストをいただければ幸いです。


7
JCommanderが気に入って良かった:-)フラグの処理方法にあまり意味を加えたくなかったので、使用する注釈に同義語を追加するだけです:@Parameter(names = {"-h"、 "- -help "})妥協案だと思いました。
Cedric Beust、

14
素晴らしいツール。強力で柔軟性があり、煩わしい従来のオプションパーサーを処理する必要はありません。
IanGilham、2011年

3
うん、私はJCommanderを書いたのとまったく同じ方法で自分のコマンドライン引数パーサーを書いたと思います。すごい仕事。
SRG

9
@CedricBeust、これは素晴らしいライブラリです。ありがとうございました。ライブラリクラスに依存せずに渡すことができる独自のArgsクラスを定義できるため、非常に柔軟になります。
ブレット・ライアン

2
水から競争を吹き飛ばす!
Marcus Junius Brutus 2013

235

7
@Ben Flynnへへ、意外と面白い形のホイールがいくつかあります。それを行う方法は複数あることを示すのに、ほとんど無害な方法だと思います!
レキシカルスコープ、2011年

14
JOpt Simpleの作者が非常によく似たリストを維持していることに気づきました!テキストが必要なのは、これらのリストをテーブルにして、機能と興味のあるポイントをリストすることです。これにより、貧しいユーザーが十分な情報に基づいて選択できるようになります。
トムアンダーソン

1
私が構築したのRop - github.com/ryenus/rop、あなたはプレーンなクラスとフィールド経由でコマンドとオプションを宣言することを注釈ベースのソリューション、ビルドコマンドラインパーサにかなりの宣言的な方法を提供しています。アプリのようにGit(single-cmd)またはMaven(multi-cmd)を構築できます。
ryenus

8
リストされているプロジェクトのほとんどは、本質的に放棄されています。リストを調べた結果、アクティブに維持され人気のあるビッグヒッターは、commons-cli、jcommander、args4j、jopt-simple、picocliのようです。argparse4jやcli-parserなどの作者に謝罪-やや恣意的なランキングを作成する必要があり、上位5つを選択しました。リスト内の他のプロジェクトも人気があり、現在も活発に開発されています。
ジョージホーキンス

2
私は誰かに各パーサーの最後の安定版リリースの日付を含めるように要求します。
スレッジ

50

2020年です。CommonsCLIよりも良い結果が得られます... :-)

独自のJavaコマンドラインパーサーを構築するか、ライブラリを使用する必要がありますか?

多くの小さなユーティリティのようなアプリケーションは、おそらく追加の外部依存関係を回避するために、独自のコマンドライン解析を実行します。picocliは興味深い代替手段かもしれません。

Picocliは、強力でユーザーフレンドリーなGraalVM対応のコマンドラインアプリを簡単に構築するための最新のライブラリとフレームワークです。これは1つのソースファイルに存在するため、アプリは依存関係を追加しないようにソースとしてそれを含めることができます。

色、オートコンプリート、サブコマンドなどをサポートしています。Javaで書かれており、Groovy、Kotlin、Scalaなどから使用できます。

最小限の使用でANSIカラーを支援

特徴:

  • 注釈ベース:宣言型重複避け、プログラマの意図表現
  • 便利:ユーザー入力を解析し、1行のコードでビジネスロジックを実行します
  • 強く型付けされたすべて-コマンドラインオプションと位置パラメータ
  • POSIXクラスター化された短いオプション(<command> -xvfInputFileおよび<command> -x -v -f InputFile
  • きめの細かい制御:最小、最大、および可変数のパラメーターを許可するアリティモデル"1..*""3..5"
  • サブコマンド(任意の深さにネストすることができます)
  • 豊富な機能:構成可能な引数グループ、引用符で囲まれた引数の分割、繰り返し可能なサブコマンドなど
  • ユーザーフレンドリー:使用法ヘルプメッセージは色を使用して、オプション名などの重要な要素を他の使用法ヘルプと対比させて、ユーザーの認知負荷軽減します
  • アプリをGraalVMネイティブイメージとして配布する
  • で動作するJava 5と高いです
  • 広範かつ詳細なドキュメント

使用法のヘルプメッセージは、アノテーションを使用して簡単にカスタマイズできます(プログラミングなし)。例えば:

拡張使用ヘルプメッセージソース

使用法のヘルプメッセージが表示される可能性があることを示すために、スクリーンショットをもう1つ追加することに抵抗がありません。使い方のヘルプはあなたのアプリケーションの顔ですので、創造的で楽しんでください!

ピコクリデモ

免責事項:私はピコクリを作成しました。フィードバックや質問は大歓迎です。


5
純粋な天才!この答えが底に埋もれているのは残念です。Apache Commons CLIは冗長でバグが多く、長い間更新されていません。また、コマンドライン引数の使用履歴に基づいてターゲットを絞った広告をしたくないので、GoogleのCLIパーサーを使用したくありません。とにかく、ピコクリより少し冗長に見えます。
ピート

2
私は@Peteを2番目にここに置きました...上のリストを調べました。これは1マイルでトップの答えになるはずです。よくやった!私の要件は、Apache CLIまたはこれらの他のほとんどのパーサーではカバーできませんでした。彼らはピコクリでも挑戦的でしたが、私が望んだ構文/動作に最も近いものを与えることができ、本当に必要なものにハッキングするのに十分な柔軟性がありました。おまけとして、ANSIのおかげで見栄えが良いです。
Shai Almog、

@ShaiAlmogトップ投票の回答は10歳で古くなっています。2019年にCommons CLIを推奨することがIMHOを誤解させることに同意します。上位の回答を書き直して、最新のものにすることを検討してください。
Remko Popma

私はすでにそれを試しましたが、それでもうまくいくとは思いません... 1Picoliのような名前を選択した場合、3番目の回答をアルファベット順に並べ替えることができます;-)
Shai Almog

私の変更が元に戻された理由は、所属を開示しなかったためです(私は著者です)。他の人はその問題を抱えてはいけません。
Remko Popma

23

私はJOptを使用しましたが、とても便利でした:http ://jopt-simple.sourceforge.net/

フロントページには、約8つの代替ライブラリのリストも表示されます。それらをチェックして、ニーズに最も適したライブラリを選択してください。


21

最近誰かが注釈ベースのargs4jを私に指摘しました。私は本当にそれが好き!


1
Args4Jの+1!非常に人に優しく、柔軟性があり、理解しやすい。Java CLIアプリを構築するための標準的なライブラリにすべきだと思います。
Zearin 2013

JCommanderが処理できない、順序付けされていない(フィールドの順序で並べ替えられた)使用法の印刷を処理できること、そしてより柔軟です。
ダニエルハリ2017

@DanielHári参考までに、この機能はJCommanderに追加されました(2017年2月下旬に沿って)。
Nathan

9

これは、Bazelプロジェクトの一部としてオープンソース化されたGoogleのコマンドライン解析ライブラリです。個人的には、これが最高の方法だと思います。ApacheCLIよりもはるかに簡単です。

https://github.com/pcj/google-options

取り付け

バゼル

maven_jar(
    name = "com_github_pcj_google_options",
    artifact = "com.github.pcj:google-options:jar:1.0.0",
    sha1 = "85d54fe6771e5ff0d54827b0a3315c3e12fdd0c7",
)

Gradle

dependencies {
  compile 'com.github.pcj:google-options:1.0.0'
}

メイベン

<dependency>
  <groupId>com.github.pcj</groupId>
  <artifactId>google-options</artifactId>
  <version>1.0.0</version>
</dependency>

使用法

(s)を拡張OptionsBaseおよび定義するクラスを作成します@Option

package example;

import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsBase;

import java.util.List;

/**
 * Command-line options definition for example server.
 */
public class ServerOptions extends OptionsBase {

  @Option(
      name = "help",
      abbrev = 'h',
      help = "Prints usage info.",
      defaultValue = "true"
    )
  public boolean help;

  @Option(
      name = "host",
      abbrev = 'o',
      help = "The server host.",
      category = "startup",
      defaultValue = ""
  )
  public String host;

  @Option(
    name = "port",
    abbrev = 'p',
    help = "The server port.",
    category = "startup",
    defaultValue = "8080"
    )
    public int port;

  @Option(
    name = "dir",
    abbrev = 'd',
    help = "Name of directory to serve static files.",
    category = "startup",
    allowMultiple = true,
    defaultValue = ""
    )
    public List<String> dirs;

}

引数を解析して使用します。

package example;

import com.google.devtools.common.options.OptionsParser;
import java.util.Collections;

public class Server {

  public static void main(String[] args) {
    OptionsParser parser = OptionsParser.newOptionsParser(ServerOptions.class);
    parser.parseAndExitUponError(args);
    ServerOptions options = parser.getOptions(ServerOptions.class);
    if (options.host.isEmpty() || options.port < 0 || options.dirs.isEmpty()) {
      printUsage(parser);
      return;
    }

    System.out.format("Starting server at %s:%d...\n", options.host, options.port);
    for (String dirname : options.dirs) {
      System.out.format("\\--> Serving static files at <%s>\n", dirname);
    }
  }

  private static void printUsage(OptionsParser parser) {
    System.out.println("Usage: java -jar server.jar OPTIONS");
    System.out.println(parser.describeOptions(Collections.<String, String>emptyMap(),
                                              OptionsParser.HelpVerbosity.LONG));
  }

}

https://github.com/pcj/google-options


こんにちは、ポール。私があなたの答えやプロジェクトのドキュメントを読んだとき、それがどのようなコマンドラインで処理できるかわかりません。たとえば、のようなものを提供できますmyexecutable -c file.json -d 42 --outdir ./out。そして、私はあなたが短い/長い/説明オプションをどのように定義するかわかりません...乾杯
olibre


8

うん。

私はあなたがこのようなものを探していると思います:http : //commons.apache.org/cli

Apache Commons CLIライブラリーは、コマンド行インターフェースを処理するためのAPIを提供します。


7

私がここにいるほとんどの人は、私のやり方が嫌いな理由が1000万件もあることを知っているでしょうが、気にしないでください。私は物事をシンプルにしたいので、 '='を使用してキーを値から分離し、次のようにHashMapに格納します。

Map<String, String> argsMap = new HashMap<>();
for (String arg: args) {
    String[] parts = arg.split("=");
    argsMap.put(parts[0], parts[1]);
} 

ユーザーが引数を忘れたり、間違った引数を使用したりした場合に役立つように、期待する引数のリストを常に維持することができます。ただし、機能が多すぎる場合、このソリューションはとにかく適していません。


7

多分これら

  • Java用のJArgsコマンドラインオプション解析スイート -この小さなプロジェクトは、Javaプログラマー向けの便利でコンパクトなパッケージ済みの包括的なドキュメント化されたコマンドラインオプションパーサースイートを提供します。最初は、GNUスタイルの「getopt」と互換性のある解析が提供されています。

  • ritopt、The Ultimate Options Parser for Java-いくつかのコマンドラインオプション標準が用意されていますが、ritoptはoptパッケージで規定されている規則に従います。


6

この不幸のメタ記事はジャンプポイントとして興味深いかもしれません。

http://furiouspurpose.blogspot.com/2008/07/command-line-parsing-libraries-for-java.html


2
その人はかなり役に立たないです。「Commons CLIどうやらここで最も古いオプションであり、コメント投稿者からあまり尊敬されていないので、私はこれをあまりよく見ていませんでした。」しかし、とにかくリンクに感謝します。
James McMahon、




4

すでにSpring Bootを使用している場合、引数の解析はそのまま使用できます。

起動後に何かを実行したい場合は、ApplicationRunnerインターフェースを実装します。

@SpringBootApplication
public class Application implements ApplicationRunner {

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }

  @Override
  public void run(ApplicationArguments args) {
    args.containsOption("my-flag-option"); // test if --my-flag-option was set
    args.getOptionValues("my-option");     // returns values of --my-option=value1 --my-option=value2 
    args.getOptionNames();                 // returns a list of all available options
    // do something with your args
  }
}

あなたのrun状況が正常に起動した後にメソッドが呼び出されます。

アプリケーションコンテキストを起動するに引数アクセスする必要がある場合は、アプリケーションの引数を手動で解析するだけです。

@SpringBootApplication
public class Application implements ApplicationRunner {

  public static void main(String[] args) {
    ApplicationArguments arguments = new DefaultApplicationArguments(args);
    // do whatever you like with your arguments
    // see above ...
    SpringApplication.run(Application.class, args);
  }

}

そして最後に、Beanで引数にアクセスする必要がある場合は、次のようにインジェクトしApplicationArgumentsます。

@Component
public class MyBean {

   @Autowired
   private ApplicationArguments arguments;

   // ...
}

これは素晴らしいです:)。
ジョンハンフリーズ-

3

Argparse4jは私が見つけた中で最高です。非常に便利で強力なPythonのargparseライブラリを模倣しています。


2

軽量(jarサイズ〜20 kb)で使いやすいものが必要な場合は、argument-parserを試すことができます。ほとんどの使用例で使用でき、引数での配列の指定をサポートし、他のライブラリに依存しません。Java 1.5以上で動作します。以下の抜粋は、それを使用する方法の例を示しています。

public static void main(String[] args) {
    String usage = "--day|-d day --mon|-m month [--year|-y year][--dir|-ds directoriesToSearch]";
    ArgumentParser argParser = new ArgumentParser(usage, InputData.class);
    InputData inputData = (InputData) argParser.parse(args);
    showData(inputData);

    new StatsGenerator().generateStats(inputData);
}

その他の例はここにあります


1
リンクが死んでいる。あなたはプロジェクトを殺しましたか?:-(
beldaz

2

Apache Common CLIライブラリはスレッドセーフではないため、ライブラリの使用はお勧めしません。

静的変数とメソッドを含むステートフルクラスを使用して内部処理(例:)を実行しOptionBuilder、シングルスレッドの厳密に制御された状況でのみ使用する必要があります。


18
CLIライブラリはスレッドセーフではないことに注意してください。ただし、コマンドライン解析は通常、アプリケーションの起動時に単一のスレッドで実行され、その後、パラメーターによっては他のスレッドが起動されると想定しています。
Alexey Ivanov

0

前述のコメントの1つとして(https://github.com/pcj/google-options)から始めるのが良いでしょう。

私が追加したいことの一つは:

1)パーサーリフレクションエラーが発生した場合は、新しいバージョンのguavaを使用してみてください。私の場合:

maven_jar(
    name = "com_google_guava_guava",
    artifact = "com.google.guava:guava:19.0",
    server = "maven2_server",
)

maven_jar(
    name = "com_github_pcj_google_options",
    artifact = "com.github.pcj:google-options:jar:1.0.0",
    server = "maven2_server",
)

maven_server(
    name = "maven2_server",
    url = "http://central.maven.org/maven2/",
)

2)コマンドラインを実行する場合:

bazel run path/to/your:project -- --var1 something --var2 something -v something

3)使用法のヘルプが必要な場合は、次のように入力します。

bazel run path/to/your:project -- --help

-1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.