-1

I understand how I can parse command line strings directly and with options using args4j. But I couldn't find how to parse several arguments to a single options. What I mean is a command line like that:

java -jar myprog.jar -i firstFile secondFile thirdFile -o outputFile

So basically I want to pass undefined number of arguments for the input option. Thx.

Namal
  • 281
  • 2
  • 10
  • 1
    Does [`StringArrayOptionHandler`](https://args4j.kohsuke.org/apidocs/org/kohsuke/args4j/spi/StringArrayOptionHandler.html) help? – andrewJames Aug 20 '20 at 14:23
  • 1
    If you can parse the strings directly, consider how you can differentiate from "-i" arg and a file named "-i" (hope this leads you to some [aha I shall require files not be specified by names that...]) – Abel Aug 20 '20 at 14:25

2 Answers2

3

args4j can't do that, I think. I wouldn't use args4j, it's.. outdated.

Try jcommander. It's the exact same idea, but unlike with args4j, you can stick the jcommander take on @Option on a List<T>. See section 2.2 of the docs (click the link, go to 2.2. :P)

HOWEVER: Note that if I take your question literally, what you're asking is highly inadvisable!

In posix-style command line arguments, your string is parsed as:

  • -i firstFile - okay, firstFile is the argument for the -i option.
  • secondFile - okay, this is completely unrelated to the -i, this is a file argument.
  • thirdFile - same deal.
  • -o outFile - outFile is the argvalue for the -o switch.

What you presumably want, and how jcommander works, is that you'd have to write:

java -jar myprog.jar -i firstFile -i secondFile -i thirdFile -o outFile

if you really want -i firstFile secondFile thirdFile to work, that's a bit weird / non-standard, and naturally, when want nonstandard things, standard libraries are unlikely to be capable of delivering for you, so you'd have to write it all by hand. I'd advise you.. change what you want, a little, to fall in line with what people expect, and thus, gain the benefit of using a library to get it for you.

However, going further down this rabbithole of command line design, going with -i in1 -i in2 -i in3 is better, but still non idiomatic and unwieldy. The usual rule is that inputs are fielded via no-switch. The proper way to write your command line would be:

java -jar myprog.jar -o outFile firstFile secondFile thirdFile

This is how zip, curl, ffmpeg, java (the executable) itself, etc all work.

both args4j and jcommander can do this; args4j via @Arguments List<String> args;, jcommander via @Parameter.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • Thanks, I will follow your advice! I checked out some other tools and they don't have output switches at all and just use the last argument as output. – Namal Aug 21 '20 at 05:29
1

With arg4j, If you want to get a list linked to "i" option you can use the StringArrayOptionHandler.

With this command line:

java -jar myprog.jar -i firstFile secondFile thirdFile -o outputFile

The source code to do that is:

class Main {

    @Option(name = "-i", handler = StringArrayOptionHandler.class)
    private List<String> files;

    @Option(name = "-o")
    private String outputFile;

    public static void main(String[] args) throws Exception {
        Main bean = new Main();
        CmdLineParser parser = new CmdLineParser(bean);
        parser.parseArgument(args);

        bean.files.stream().forEach(entry -> System.out.println(entry));
        System.out.println(bean.outputFile);
    }
}

Fabien Leborgne
  • 377
  • 1
  • 5