【问题标题】:How can I get NDesk to parse multi arg lists at the command line?如何让 NDesk 在命令行解析多参数列表?
【发布时间】:2013-01-22 08:50:15
【问题描述】:

如何让 NDesk 在命令行 (C#) 解析多参数列表?

我有两个标志,它们都带有多个参数(文件列表)。所以一个是-j,另一个是-c。但我认为 NDesk 要求这些参数中的每一个都以 -j/-c) 开头)

例如我想要:

%> main -j file1.j file2.j file3.j -c file4.c file5.c file6.c file7.c

并让它生成 2 个列表,一个包含 .j 文件,另一个包含 .c 文件。但是,它希望以这种方式列出的每个文件都以该标志开头。

所以这会起作用:

%> main -j file1.j -j file2.j -j file3.j -c file4.c -c file5.c -c file6.c -c file7.c

虽然我宁愿拥有第一个版本。

有没有办法用 NDesk.Options 库做到这一点?我已经阅读了大部分文档,但我认为不是。

【问题讨论】:

标签: c# command-line-arguments ndesk.options


【解决方案1】:

有一种方法可以做到这一点,但它需要一点技巧。 NDesk 使用“”作为特殊的默认处理程序。您所做的是跟踪“当前”参数,然后让默认处理程序根据当前参数决定如何处理这些值。这是我将值放入字典的示例。

static void Main(string[] args)
{
    string currentParameter = "";
    Dictionary<string, List<string>> parameters = new Dictionary<string, List<string>>();
    OptionSet set = new OptionSet() {
            { "c", ".c files", v => currentParameter = "c" },
            { "j", ".j files", v => currentParameter = "j" },
            { "<>", v => {

                    List<string> values;
                    if (parameters.TryGetValue(currentParameter, out values))
                    {
                        values.Add(v);
                    }
                    else
                    {
                        values = new List<string> { v };
                        parameters.Add(currentParameter, values);
                    }

                }
            }
        };

    set.Parse(args);
    foreach (var parameter in parameters)
    {
        Console.WriteLine("Parameter: {0}", parameter.Key);
        foreach (var value in parameter.Value)
        {
            Console.WriteLine("\t{0}", value);
        }
    }
}

输出是:

参数:j
文件 1.j
文件2.j
文件3.j
参数:c
文件 4.c
文件 5.c
文件6.c
文件 7.c

【讨论】:

  • 技术上the spec 支持“贪婪”选项,但看起来您必须覆盖OptionSet 并自己编写以支持此功能;否则使用此解决方案。
【解决方案2】:

另一种方法是覆盖OptionSet.Parseas outlined here

该示例描述了一种更彻底的“连接/附加”方法,它将解析所有格式,但如果您只是对处理 -flag value1 value2 value3 ... valueN 感兴趣,那么您可以使用:

public class MultiOptionSet : OptionSet
{
    private string lastArg;
    private Option lastOption;

    protected override bool Parse(string argument, OptionContext c)
    {
        // based on example in http://www.ndesk.org/doc/ndesk-options/NDesk.Options/Option.html#M:NDesk.Options.Option.OnParseComplete(NDesk.Options.OptionContext)

        string f, n, s, v;
        bool haveParts = GetOptionParts(argument, out f, out n, out s, out v);

        // reset placeholder for next multiple if we are looking at a flagged argument name
        if( haveParts )
        {
            lastArg = f + n;
        }
        // are we after a flagged argument name, without parts (meaning a value)
        else
        {
            // remember for next time, in case it's another value
            if( null != c.Option ) lastOption = c.Option;
            // but if the 'last arg' wasn't already provided, we reuse the one we set last time
            else
            {
                c.Option = lastOption;
                c.OptionName = lastArg;
            }

            c.OptionValues.Add(argument); // add the value to be invoked
            c.Option.Invoke(c); // perform the 'setter'
            return true;
        }

        return base.Parse(argument, c);
    }
}

【讨论】:

  • hm...似乎处理/flag:value1 value2 value3-flagvalue1 value2 value3就好了...
猜你喜欢
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 2013-03-21
  • 2021-07-27
相关资源
最近更新 更多