BLOGTIMES
2011/09/02

JOpt Simple でコマンドラインオプションをパースする

  java  cli 
このエントリーをはてなブックマークに追加

ひとまずオプションのパースはApache Commons CLI でできるようになったのですが、もう一つくらい調べておこうということで $ --jopt-simple というライブラリを調べてみました。

JOpt Simple - a Java command line parsing library - JOpt Simple

JOpt Simple is a Java library for parsing command line options, such as those you might pass to an invocation of javac.
In the interest of striving for simplicity, as closely as possible JOpt Simple attempts to honor the command line option syntaxes of POSIX getopt() and GNU getopt_long(). It also aims to make option parser configuration and retrieval of options and their arguments simple and expressive, without being overly clever.

以下、作業メモ。

対象とするオプション

先ほどと同様にこんなコマンドをとるコマンドを想定してみます。

-a aaa [-b] [-c ccc] [-d [ddd]] eee.txt

標準のヘルプ生成を使うとこんな感じのヘルプが生成されます。

$ java -jar JoptSimpleExample.jar -a aaa -h Option (* = required) Description --------------------- ----------- -a -b -c -d (default: ddd) -h

こちらも先ほどと同じ条件でテストしてみた結果がこちら。

$ java -jar JoptSimpleExample.jar -a aaa -- eee.txt -a, a = aaa, d = ddd, 残りのパラメータ -> eee.txt,
$ java -jar JoptSimpleExample.jar -a aaa -b -- eee.txt -a, a = aaa, -b, d = ddd, 残りのパラメータ -> eee.txt,
$ java -jar JoptSimpleExample.jar -a aaa -b -c ccc -- eee.txt -a, a = aaa, -b, -c, c = ccc, d = ddd, 残りのパラメータ -> eee.txt,
$ java -jar JoptSimpleExample.jar -a aaa -b -c ccc -d -- eee.txt -a, a = aaa, -b, -c, c = ccc, -d, d = ddd, 残りのパラメータ -> eee.txt,
$ java -jar JoptSimpleExample.jar -a aaa -b -c ccc -d dnew -- eee.txt -a, a = aaa, -b, -c, c = ccc, -d, d = dnew, 残りのパラメータ -> eee.txt,
$ java -jar JoptSimpleExample.jar eee.txt Exception in thread "main" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58) Caused by: joptsimple.MissingRequiredOptionException: Missing required option ['a'] at joptsimple.OptionParser.ensureRequiredOptions(OptionParser.java:385) at joptsimple.OptionParser.parse(OptionParser.java:372) at JOptSimpleExample.main(JOptSimpleExample.java:26) ... 5 more
$ java -jar JoptSimpleExample.jar -a aaa fff -- eee.txt -a, a = aaa, d = ddd, 残りのパラメータ -> fff, eee.txt,
$ java -jar JoptSimpleExample.jar -a aaa -b bbb -- eee.txt -a, a = aaa, -b, d = ddd, 残りのパラメータ -> bbb, eee.txt,
$ java -jar JoptSimpleExample.jar -a aaa -b -c -- eee.txt -a, a = aaa, -b, -c, c = --, d = ddd, 残りのパラメータ -> eee.txt,
$ java -jar JoptSimpleExample.jar -a aaa -b -c -d -- eee.txt -a, a = aaa, -b, -c, c = -d, d = ddd, 残りのパラメータ -> eee.txt,
$ java -jar JoptSimpleExample.jar -a aaa -b -d dnew ggg -- eee.txt -a, a = aaa, -b, -d, d = dnew, 残りのパラメータ -> ggg, eee.txt,

こちらはオプションの引数を指定できないので、パースエラーになるパターンが1つ少ない&値がずれたりしているので、今回のような使い方だと Commons CLI の方がきれいに書けるようですね。あとはこっちはパースエラーが検査例外じゃないというところが違いますね。まぁ結局は好みの問題でしょうけど。

サンプルコード

JOptSimpleExample.java

import joptsimple.OptionParser; import joptsimple.OptionSet; public class JOptSimpleExample { public static void main(String[] args) throws Exception { OptionParser parser = new OptionParser() { { // -a の定義 accepts("a").withRequiredArg().required(); // -b の定義 accepts("b"); // -c の定義 accepts("c").withRequiredArg(); // -d の定義 accepts("d").withOptionalArg().defaultsTo("ddd"); // help の定義 accepts("h"); } }; // argsのパース OptionSet options = parser.parse(args); // 取得結果の処理 if( options.has("h") ) parser.printHelpOn(System.out); if( options.has("a") ){ System.out.print("-a, "); System.out.print("a = "+ options.valueOf("a")+", "); } if( options.has("b") ){ System.out.print("-b, "); } if( options.has("c") ){ System.out.print("-c, "); System.out.print("c = "+ options.valueOf("c")+", "); } if( options.has("d") ){ System.out.print("-d, "); } System.out.print("d = "+ options.valueOf("d")+", "); System.out.print("残りのパラメータ -> "); for( String s : options.nonOptionArguments()){ System.out.print(s + ", "); } } }

    トラックバックについて
    Trackback URL:
    お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
    このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/4424
    Trackbacks
    このエントリにトラックバックはありません
    Comments
    愛のあるツッコミをお気軽にどうぞ。[policy]
    古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
    コメントはありません
    Comments Form

    コメントは承認後の表示となります。
    OpenIDでログインすると、即時に公開されます。

    OpenID を使ってログインすることができます。

    Identity URL: Yahoo! JAPAN IDでログイン