【问题标题】:How to parse file patterns using Apache commons CLI如何使用 Apache commons CLI 解析文件模式
【发布时间】:2018-02-14 00:14:11
【问题描述】:

我正在尝试使用 apache commons CLI 解析我的命令行参数。这里的示例可能有点笨拙,但在我正在创建的程序的上下文中它是有意义的。我正在尝试读取文件模式过滤器,类似于 grep 用于选择要处理的文件。

我的论点如下所示:

Program --input *.*

我写了一个测试程序来看看解析器看到了什么;

public static void main(String[] args) {

    Options options = new Options();
    options.addOption(new Option(INPUT_FILTER_SHORT, INPUT_FILTER_LONG, true, INPUT_FILTER_DESCRIPTION));

    CommandLineParser parser = new BasicParser();
    CommandLine cmd = parser.parse(options, args);

    System.out.println(cmd.getOptionValue(INPUT_FILTER_SHORT));
}

打印出来:

.classpath

如果我将参数更改为:

Program --input test.txt

我得到了输出:

test.txt

我假设我必须做一些事情来告诉 apache commons 什么 * 不是特殊字符?我似乎无法在网上找到有关此的任何信息。

我在 Windows (7) 上遇到了这种情况。我相当确定是 *.* 导致了问题,因为当我切换到使用不使用 * 的模式时,会出现预期的模式。

【问题讨论】:

  • 如果用引号将*.* 括起来会发生什么(尝试单引号和双引号)?示例:Program --input "*.*"
  • 我刚刚更新了帖子,但这发生在 Windows 7 上。当我用单引号括起来时,它会打印出 '.'(包括引号),当我双引号,它打印出'.classpath'

标签: java apache command-line apache-commons-cli


【解决方案1】:

您的问题实际上与 Commons CLI 无关,而是与 shell 和 Java 可执行文件如何一起处理参数有关。

要消除其他因素,看看发生了什么,请使用一个简短的 Java 程序:

public class ArgsDemo {
     public static void main(String[] args) {
         for(int i=0; i<args.length; i++) {
              System.out.println("" + i + ": " + args[i]);
         }
     }
}

java ArgsDemo hello worldjava ArgsDemo * 等一起玩,观察会发生什么。

在 UNIX 和 Linux 上:

Java 不对* 进行特殊处理。但是,shell 可以。所以如果你这样做了:

$ mkdir x
$ cd x
$ touch a b
$ java -jar myjar.jar MyClass *

...然后MyClass.main() 将使用参数数组["a","b"] 调用——因为UNIX shell 将* 扩展为当前目录中的文件。

你可以通过转义来抑制它:

$ java -jar myjar MyClass *  // main() sees ["*"])

(请注意,UNIX shell 不会将 *.* 扩展为 .classpath,因为这种形式会忽略以 . 开头的“隐藏”文件)

在 Windows 上

cmd.exe 不进行 UNIX 风格的通配符扩展。如果您将* 作为参数提供给Windows 中的命令,则该命令将获得文字*。例如,PKUNZIP *.zip*.zip 传递给 PKUNZIP.EXE,如果它愿意,则由该程序来扩展通配符。

从 Java 7 的某些版本开始,Windows 的 Java 可执行文件对自己的文件名扩展做了一些通配符,将参数传递给您的 main() 类。

我无法找到 Java-for-Windows 通配符扩展规则的明确文档,但您应该能够通过引用来控制它,转义引号以防止 cmd.exe 解释它们:

> java.exe -jar myjar.jar MyClass """*.*"""

(未经测试,因为我手边没有 Windows 框,在 cmd.exe 中引用有点像野兽 - 请尝试并编辑以上内容或发表评论)

【讨论】:

  • 不幸的是(或幸运的是:D)我没有要测试的 Windows 系统 - 但我认为按照 Windows 的规则 *.* 匹配 .classpath 是合理的。
  • 请参阅stackoverflow.com/questions/562038/…,了解 Windows 中转义引号上方的血腥细节。
猜你喜欢
  • 1970-01-01
  • 2015-08-28
  • 2023-03-22
  • 1970-01-01
  • 2012-07-10
  • 1970-01-01
  • 1970-01-01
  • 2017-09-11
  • 1970-01-01
相关资源
最近更新 更多