2011-09-07 23 views
33

क्या होगा यदि मैं इस पार्स करने के लिए चाहता था:पार्सिंग तर्क

java MyProgram -r opt1 -S opt2 arg1 arg2 arg3 arg4 --test -A opt3 

और परिणाम मैं अपने कार्यक्रम में चाहते हैं:

regular Java args[] of size=4 
org.apache.commons.cli.Options[] of size=3 
org.apache.commons.cli.Options[] #2 of size=1 

मैं Apache Commons CLI उपयोग करने के लिए पसंद करते हैं, लेकिन दस्तावेज ऊपर मौजूद मामले के बारे में थोड़ा अस्पष्ट है।

1. options with a "-" char 
2. options with a "--" char 
3. options without any marker, or "bare args" 

काश कि अपाचे कॉमन्स CLI काम करते हैं लेकिन अभी भी करने के लिए नियमित रूप से आर्ग पारित करने में सक्षम होगा: विशेष रूप से, प्रलेखन कैसे 3 प्रकार के विकल्पों को संभालने के लिए मैं नीचे निर्दिष्ट आपको बता नहीं है प्रोग्राम अगर उन तर्कों में विकल्प उपसर्ग नहीं था। शायद यह करता है लेकिन प्रलेखन ऐसा नहीं कहता है क्योंकि मैंने इसे पढ़ा है ...

+1

संभावित डुप्लिकेट (http://stackoverflow.com/questions/367706/how-to-parse-command- लाइन-तर्क-इन-जावा) – xenteros

उत्तर

19

आप इसे मैन्युअल रूप से कर सकते हैं।

एनबी: ऑप्ट्स के लिए एक आंतरिक कक्षा के बजाय हैश मैप का उपयोग करना बेहतर हो सकता है।

/** convenient "-flag opt" combination */ 
private class Option { 
    String flag, opt; 
    public Option(String flag, String opt) { this.flag = flag; this.opt = opt; } 
} 

static public void main(String[] args) { 
    List<String> argsList = new ArrayList<String>(); 
    List<Option> optsList = new ArrayList<Option>(); 
    List<String> doubleOptsList = new ArrayList<String>(); 

    for (int i = 0; i < args.length; i++) { 
     switch (args[i].charAt(0)) { 
     case '-': 
      if (args[i].length < 2) 
       throw new IllegalArgumentException("Not a valid argument: "+args[i]); 
      if (args[i].charAt(1) == '-') { 
       if (args[i].length < 3) 
        throw new IllegalArgumentException("Not a valid argument: "+args[i]); 
       // --opt 
       doubleOptsList.add(args[i].substring(2, args[i].length)); 
      } else { 
       if (args.length-1 == i) 
        throw new IllegalArgumentException("Expected arg after: "+args[i]); 
       // -opt 
       optsList.add(new Option(args[i], args[i+1])); 
       i++; 
      } 
      break; 
     default: 
      // arg 
      argsList.add(args[i]); 
      break; 
     } 
    } 
    // etc 
} 
+1

आपको तर्कों की लंबाई जांचनी चाहिए [i]! –

+0

मैं बस उसमें टाइप कर रहा था! यदि आप फैंसी बनना चाहते हैं तो आप स्विच स्टेटमेंट के बजाय हैश टेबल का भी उपयोग कर सकते हैं। – IslandCow

+0

@ जोन ब्राइट बेहतर है? –

0

ठीक है, इस अवधारणा के लिए चार्ल्स गुडविन के लिए धन्यवाद।

import java.util.*; 
public class Test { 

    public static void main(String[] args) { 
    List<String> argsList = new ArrayList<String>(); 
    List<String> optsList = new ArrayList<String>(); 
    List<String> doubleOptsList = new ArrayList<String>(); 
    for (int i=0; i < args.length; i++) { 
     switch (args[i].charAt(0)) { 
     case '-': 
      if (args[i].charAt(1) == '-') { 
       int len = 0; 
       String argstring = args[i].toString(); 
       len = argstring.length(); 
       System.out.println("Found double dash with command " + 
        argstring.substring(2, len)); 
       doubleOptsList.add(argstring.substring(2, len));   
      } else { 
       System.out.println("Found dash with command " + 
        args[i].charAt(1) + " and value " + args[i+1]); 
       i= i+1; 
       optsList.add(args[i]);  
      }   
     break;   
     default:    
     System.out.println("Add a default arg."); 
     argsList.add(args[i]); 
     break;   
     }  
    } 
    } 

} 
+1

यह अभी भी सही नहीं है क्योंकि आप '-फ्लैग ऑप्ट' संयोजन को संग्रहीत नहीं कर रहे हैं। –

+0

मैंने इसे बीन्सहेल समाधान के रूप में लिखा: http: // stackoverflow।कॉम/प्रश्न/7356979/जावा-बीन्सहेल-स्क्रिप्टिंग-द-एर्ग्स-टू-द-द-प्रोग्राम – djangofan

44

ARG1, ARG2, arg3, और arg4 पाने के लिए Apache Commons CLI library commandline.getArgs() का उपयोग: यहाँ जवाब है। जावा में कमांड लाइन के लिए



    import org.apache.commons.cli.CommandLine; 
    import org.apache.commons.cli.Option; 
    import org.apache.commons.cli.Options; 
    import org.apache.commons.cli.Option.Builder; 
    import org.apache.commons.cli.CommandLineParser; 
    import org.apache.commons.cli.DefaultParser; 
    import org.apache.commons.cli.ParseException; 

    public static void main(String[] parameters) 
    { 
     CommandLine commandLine; 
     Option option_A = Option.builder("A") 
      .required(true) 
      .desc("The A option") 
      .longOpt("opt3") 
      .build(); 
     Option option_r = Option.builder("r") 
      .required(true) 
      .desc("The r option") 
      .longOpt("opt1") 
      .build(); 
     Option option_S = Option.builder("S") 
      .required(true) 
      .desc("The S option") 
      .longOpt("opt2") 
      .build(); 
     Option option_test = Option.builder() 
      .required(true) 
      .desc("The test option") 
      .longOpt("test") 
      .build(); 
     Options options = new Options(); 
     CommandLineParser parser = new DefaultParser(); 

     String[] testArgs = 
     { "-r", "opt1", "-S", "opt2", "arg1", "arg2", 
      "arg3", "arg4", "--test", "-A", "opt3", }; 

     options.addOption(option_A); 
     options.addOption(option_r); 
     options.addOption(option_S); 
     options.addOption(option_test); 

     try 
     { 
      commandLine = parser.parse(options, testArgs); 

      if (commandLine.hasOption("A")) 
      { 
       System.out.print("Option A is present. The value is: "); 
       System.out.println(commandLine.getOptionValue("A")); 
      } 

      if (commandLine.hasOption("r")) 
      { 
       System.out.print("Option r is present. The value is: "); 
       System.out.println(commandLine.getOptionValue("r")); 
      } 

      if (commandLine.hasOption("S")) 
      { 
       System.out.print("Option S is present. The value is: "); 
       System.out.println(commandLine.getOptionValue("S")); 
      } 

      if (commandLine.hasOption("test")) 
      { 
       System.out.println("Option test is present. This is a flag option."); 
      } 

      { 
       String[] remainder = commandLine.getArgs(); 
       System.out.print("Remaining arguments: "); 
       for (String argument : remainder) 
       { 
        System.out.print(argument); 
        System.out.print(" "); 
       } 

       System.out.println(); 
      } 

     } 
     catch (ParseException exception) 
     { 
      System.out.print("Parse error: "); 
      System.out.println(exception.getMessage()); 
     } 
    } 

+0

इस उत्तर में कुछ दृष्टिकोण अब समर्थित नहीं हैं। वर्तमान सीएलआई संस्करण के लिए उदाहरण: https://commons.apache.org/proper/commons-cli/usage.html – stuart

0

सरल कोड:

class CMDLineArgument 
{ 
    public static void main(String args[]) 
    { 
     String name=args[0]; 
     System.out.println(name); 
    } 
} 
2

आप https://github.com/jankroken/commandline इस्तेमाल कर सकते हैं, यहाँ है कि कैसे करना है: यहाँ कुछ कोड है

इस उदाहरण के काम करने के लिए, मैं चाहिए तर्कों के बारे में धारणाएं बनाएं - बस कुछ चुनना ...

-r opt1 => replyAddress=opt1 
-S opt2 arg1 arg2 arg3 arg4 => subjects=[opt2,arg1,arg2,arg3,arg4] 
--test = test=true (default false) 
-A opt3 => address=opt3 

public class MyProgramOptions { 
    private String replyAddress; 
    private String address; 
    private List<String> subjects; 
    private boolean test = false; 

    @ShortSwitch("r") 
    @LongSwitch("replyAddress") // if you also want a long variant. This can be skipped 
    @SingleArgument 
    public void setReplyAddress(String replyAddress) { 
    this.replyAddress = replyAddress; 
    } 

    @ShortSwitch("S") 
    @AllAvailableArguments 
    public void setSubjects(List<String> subjects) { 
    this.subjects = subjects; 
    } 

    @LongSwitch("test") 
    @Toggle(true) 
    public void setTest(boolean test) { 
    this.test = test; 
    } 

    @ShortSwitch("A") 
    @SingleArgument 
    public void setAddress(String address) { 
    this.address = address; 
    } 

    // getters... 
} 

और फिर मुख्य विधि में, आप बस कर सकते हैं::

public final static void main(String[] args) { 
    try { 
    MyProgramOptions options = CommandLineParser.parse(MyProgramOptions.class, args, OptionStyle.SIMPLE); 

    // and then you can pass options to your application logic... 

    } catch 
    ... 
    } 
} 
9

मैं यह पसंद है तो इस तरह से स्थापित किया जा सकता। सरल और आप प्रत्येक तर्क के लिए एक से अधिक पैरामीटर है है:

final Map<String, List<String>> params = new HashMap<>(); 

List<String> options = null; 
for (int i = 0; i < args.length; i++) { 
    final String a = args[i]; 

    if (a.charAt(0) == '-') { 
     if (a.length() < 2) { 
      System.err.println("Error at argument " + a); 
      return; 
     } 

     options = new ArrayList<>(); 
     params.put(a.substring(1), options); 
    } 
    else if (options != null) { 
     options.add(a); 
    } 
    else { 
     System.err.println("Illegal parameter usage"); 
     return; 
    } 
} 

उदाहरण के लिए:

-arg1 1 2 --arg2 3 4 

System.out.print(params.get("arg1").get(0)); // 1 
System.out.print(params.get("arg1").get(1)); // 2 
System.out.print(params.get("-arg2").get(0)); // 3 
System.out.print(params.get("-arg2").get(1)); // 4 
+0

मुझे आश्चर्य है कि वहां कोई लाइब्रेरी नहीं है जो यह सुरुचिपूर्ण तरीका है। अन्य सभी आपके कोड को एक या दूसरे तरीके से समझौता करते हैं (अनावश्यक कोड, परिवर्तनीय स्थिति, अतिरिक्त कन्स्ट्रक्टर कॉल)। –

+0

संवर्द्धन अनुरोध - क्या आप इस जवाब को बराबर डिलीमीटर स्वीकार करने के लिए संशोधित कर सकते हैं? :) मैं खुद को अनुमान लगाऊंगा लेकिन आप इसे करते हैं। –

1

आप REFCODES पर refcodes-console पर refcodes-console विरूपण साक्ष्य इस्तेमाल कर सकते हैं।ओआरजी:,

ArgsParser theArgsParser = new ArgsParserImpl(theRoot); 
theArgsParser.setName("MyProgramm"); 
theArgsParser.setSyntaxNotation(SyntaxNotation.GNU_POSIX); 

से ऊपर है कि आप अपने वाक्य रचना को परिभाषित नीचे आप पार्सर आह्वान:

Option<String> r  = new StringOptionImpl("-r", null, "opt1", "..."); 
Option<String> s  = new StringOptionImpl("-S", null, "opt2", "..."); 
Operand<String> arg1 = new StringOperandImpl("arg1", "..."); 
Operand<String> arg2 = new StringOperandImpl("arg2", "..."); 
Operand<String> arg3 = new StringOperandImpl("arg3", "..."); 
Operand<String> arg4 = new StringOperandImpl("arg4", "..."); 
Switch test   = new SwitchImpl(null, "--test", "..."); 
Option<String> a  = new StringOptionImpl("-A", null, "opt3", "..."); 
Condition theRoot = new AndConditionImpl(r, s, a, arg1, arg2, arg3, arg4, 
    test); 

अपने तर्क अपने जड़ शर्त के साथ पार्सर ArgsParserImpl बनाएं

theArgsParser.printUsage(); 
theArgsParser.printSeparatorLn(); 
theArgsParser.printOptions(); 
theArgsParser.evalArgs(new String[] { 
    "-r", "RRRRR", "-S", "SSSSS", "11111", "22222", "33333", "44444", 
    "--test", "-A", "AAAAA" 
}); 

मामले में आप कुछ प्रदान की अच्छे विवरण, theArgsParser.printUsage() आपको सुंदर मुद्रित उपयोग भी दिखाएगा:

Usage: MyProgramm -r <opt1> -S <opt2> -A <opt3> arg1 arg2 arg3 arg4 --test 

ऊपर के उदाहरण में सभी परिभाषित तर्क उपयोगकर्ता द्वारा पास किया जाना चाहिए, और पार्सर एक गलत उपयोग की पहचान करेगा। , नई

theRoot = नए AndConditionImpl (आर, एस, एक, ARG1, ARG2, arg3, arg4: मामले में --test स्विच, वैकल्पिक (या किसी अन्य तर्क) हो इस प्रकार theRoot आवंटित करने के लिए है वैकल्पिक Impl (परीक्षण));

फिर अपने वाक्य रचना के रूप में निम्नानुसार है:

Usage: MyProgramm -r <opt1> -S <opt2> -A <opt3> arg1 arg2 arg3 arg4 [--test] 

अपने मामले के लिए पूर्ण उदाहरण आप StackOverFlowExamle में पाते हैं। आप AND, OR, XOR स्थितियों और किसी भी तरह के घोंसले का उपयोग कर सकते हैं ... उम्मीद है कि इससे मदद मिलती है। r.getValue()); या if (test.getValue() == true) ...:

इस प्रकार पार्स तर्क मूल्यांकन

LOGGER.info("r :=" + r.getValue()); 
LOGGER.info("S :=" + s.getValue()); 
LOGGER.info("arg1 :=" + arg1.getValue()); 
LOGGER.info("arg2 :=" + arg2.getValue()); 
LOGGER.info("arg3 :=" + arg3.getValue()); 
LOGGER.info("arg4 :=" + arg4.getValue()); 
LOGGER.info("test :=" + test.getValue() + ""); 
LOGGER.info("A :=" + a.getValue()); 
+1

ओह लड़का आपकी लाइब्रेरी कई डीपी में खींचती है। मैंने गिनती बंद कर दी। क्षमा करें, मेरे लिए नहीं करेंगे। – peterh

+0

आप सही हैं। मैंने इसे संस्करण ** 1.1.0 ** के साथ तय किया है, जो अब केंद्रीय केंद्र [1] के लिए जारी किया गया है। रिफ्रोड निर्भरता को छोड़कर संकलन समय निर्भरता [2] मैं इस आदेश के साथ निर्धारित करता हूं: 'एमवीएन निर्भरता: सूची -डिन्डेस्कोस्कोप = संकलन -डिक्स शामिल करें = परीक्षण | grep -v refcodes' परिणाम से एक झूठी सकारात्मक [3] को हटाकर, मैं संस्करण ** 1.1.0 **: 'jline: jline: jar: 2.14.2: compile' के लिए उन निर्भरताओं के साथ समाप्त होता हूं 'log4j: log4j: jar: 1.2.17: संकलन ' इनपुट के लिए धन्यवाद और उम्मीद है कि यह मदद करता है! :-) –

+0

[1] संस्करण 1.1.0 के लिए रीफ्रोड [परिवर्तन-सूची] (http://www.refcodes.org/refcodes/refcodes.org_change_list_version_1.1.0) देखें। [2] उन्हें रीफ्रोड कलाकृतियों एक स्रोत, एक संस्करण, सभी सिंक में जारी किए गए हैं और चिंताओं और मॉड्यूलरलाइजेशन को अलग करने के रूप में मॉड्यूल में विभाजित हैं, इसके अलावा सभी https://bitbucket.org/refcodes पर स्थित हैं। [3] देखें [निर्भरता क्यों है: सूची ... परीक्षण स्कोप आइटमों की संक्रमणीय निर्भरताओं के लिए संकलन गुंजाइश सूचीबद्ध करता है] (http://stackoverflow.com/questions/17237281/why-does- निर्भरतासूची- dincludescope-compile-lists -compile-गुंजाइश के लिए transiti) –

1

यहाँ @DwB समाधान कॉमन्स CLI 1.3.1 अनुपालन (प्रतिस्थापित पदावनत घटकों OptionBuilder और GnuParser) करने के लिए उन्नत है। अपाचे दस्तावेज़ उदाहरणों का उपयोग करता है कि वास्तविक जीवन में अनमार्क/बेयर तर्क हैं लेकिन उन्हें अनदेखा करते हैं। यह दिखाने के लिए धन्यवाद @ डीडब्ल्यूबी यह कैसे काम करता है।

import org.apache.commons.cli.CommandLine; 
import org.apache.commons.cli.CommandLineParser; 
import org.apache.commons.cli.DefaultParser; 
import org.apache.commons.cli.HelpFormatter; 
import org.apache.commons.cli.Option; 
import org.apache.commons.cli.Options; 
import org.apache.commons.cli.ParseException; 

public static void main(String[] parameters) { 
    CommandLine commandLine; 
    Option option_A = Option.builder("A").argName("opt3").hasArg().desc("The A option").build(); 
    Option option_r = Option.builder("r").argName("opt1").hasArg().desc("The r option").build(); 
    Option option_S = Option.builder("S").argName("opt2").hasArg().desc("The S option").build(); 
    Option option_test = Option.builder().longOpt("test").desc("The test option").build(); 
    Options options = new Options(); 
    CommandLineParser parser = new DefaultParser(); 

    options.addOption(option_A); 
    options.addOption(option_r); 
    options.addOption(option_S); 
    options.addOption(option_test); 

    String header = "    [<arg1> [<arg2> [<arg3> ...\n  Options, flags and arguments may be in any order"; 
    String footer = "This is DwB's solution brought to Commons CLI 1.3.1 compliance (deprecated methods replaced)"; 
    HelpFormatter formatter = new HelpFormatter(); 
    formatter.printHelp("CLIsample", header, options, footer, true);  

    String[] testArgs = 
      { "-r", "opt1", "-S", "opt2", "arg1", "arg2", 
        "arg3", "arg4", "--test", "-A", "opt3", }; 

    try 
    { 
     commandLine = parser.parse(options, testArgs); 

     if (commandLine.hasOption("A")) 
     { 
      System.out.print("Option A is present. The value is: "); 
      System.out.println(commandLine.getOptionValue("A")); 
     } 

     if (commandLine.hasOption("r")) 
     { 
      System.out.print("Option r is present. The value is: "); 
      System.out.println(commandLine.getOptionValue("r")); 
     } 

     if (commandLine.hasOption("S")) 
     { 
      System.out.print("Option S is present. The value is: "); 
      System.out.println(commandLine.getOptionValue("S")); 
     } 

     if (commandLine.hasOption("test")) 
     { 
      System.out.println("Option test is present. This is a flag option."); 
     } 

     { 
      String[] remainder = commandLine.getArgs(); 
      System.out.print("Remaining arguments: "); 
      for (String argument : remainder) 
      { 
       System.out.print(argument); 
       System.out.print(" "); 
      } 

      System.out.println(); 
     } 

    } 
    catch (ParseException exception) 
    { 
     System.out.print("Parse error: "); 
     System.out.println(exception.getMessage()); 
    } 

} 

आउटपुट: [? कैसे जावा में आदेश पंक्ति तर्क पार्स करने के लिए]

usage: CLIsample [-A <opt3>] [-r <opt1>] [-S <opt2>] [--test] 
       [<arg1> [<arg2> [<arg3> ... 
     Options, flags and arguments may be in any order 
-A <opt3> The A option 
-r <opt1> The r option 
-S <opt2> The S option 
    --test The test option 
This is DwB's solution brought to Commons CLI 1.3.1 compliance (deprecated 
methods replaced) 
Option A is present. The value is: opt3 
Option r is present. The value is: opt1 
Option S is present. The value is: opt2 
Option test is present. This is a flag option. 
Remaining arguments: arg1 arg2 arg3 arg4 
की
संबंधित मुद्दे