매개 변수를 사용하는 콘솔 응용 프로그램을 빌드 할 때에 전달 된 인수를 사용할 수 있습니다 Main(string[] args)
.
과거에는 단순히 해당 배열을 인덱싱 / 루프하고 몇 가지 정규 표현식을 수행하여 값을 추출했습니다. 그러나 명령이 더 복잡해지면 구문 분석이 매우 어려워 질 수 있습니다.
그래서 나는 관심이 있습니다 :
- 사용하는 라이브러리
- 사용하는 패턴
매개 변수를 사용하는 콘솔 응용 프로그램을 빌드 할 때에 전달 된 인수를 사용할 수 있습니다 Main(string[] args)
.
과거에는 단순히 해당 배열을 인덱싱 / 루프하고 몇 가지 정규 표현식을 수행하여 값을 추출했습니다. 그러나 명령이 더 복잡해지면 구문 분석이 매우 어려워 질 수 있습니다.
그래서 나는 관심이 있습니다 :
답변:
NDesk.Options ( Documentation ) 및 / 또는 Mono.Options (동일한 API, 다른 네임 스페이스)를 사용하는 것이 좋습니다 . 설명서 의 예 :
bool show_help = false;
List<string> names = new List<string> ();
int repeat = 1;
var p = new OptionSet () {
{ "n|name=", "the {NAME} of someone to greet.",
v => names.Add (v) },
{ "r|repeat=",
"the number of {TIMES} to repeat the greeting.\n" +
"this must be an integer.",
(int v) => repeat = v },
{ "v", "increase debug message verbosity",
v => { if (v != null) ++verbosity; } },
{ "h|help", "show this message and exit",
v => show_help = v != null },
};
List<string> extra;
try {
extra = p.Parse (args);
}
catch (OptionException e) {
Console.Write ("greet: ");
Console.WriteLine (e.Message);
Console.WriteLine ("Try `greet --help' for more information.");
return;
}
git checkout master
), 또는 인수 (즉, 지원하지 않는 유연한 아니다 --foo 123
= --foo=123
= -f 123
= -f=123
또한 -v -h
= -vh
).
나는 커맨드 라인 파서 라이브러리 ( http://commandline.codeplex.com/ )를 정말 좋아합니다 . 속성을 통해 매개 변수를 설정하는 매우 간단하고 우아한 방법이 있습니다.
class Options
{
[Option("i", "input", Required = true, HelpText = "Input file to read.")]
public string InputFile { get; set; }
[Option(null, "length", HelpText = "The maximum number of bytes to process.")]
public int MaximumLenght { get; set; }
[Option("v", null, HelpText = "Print details during execution.")]
public bool Verbose { get; set; }
[HelpOption(HelpText = "Display this help screen.")]
public string GetUsage()
{
var usage = new StringBuilder();
usage.AppendLine("Quickstart Application 1.0");
usage.AppendLine("Read user manual for usage instructions...");
return usage.ToString();
}
}
--recursive
도 지원하는 것 같습니다 .
WPF TestApi 라이브러리는 C #을 개발을위한 좋은 명령 줄 파서 중 하나와 함께 제공됩니다. API에 대한 Ivo Manolov의 블로그 에서 살펴 보는 것이 좋습니다 .
// EXAMPLE #2:
// Sample for parsing the following command-line:
// Test.exe /verbose /runId=10
// This sample declares a class in which the strongly-
// typed arguments are populated
public class CommandLineArguments
{
bool? Verbose { get; set; }
int? RunId { get; set; }
}
CommandLineArguments a = new CommandLineArguments();
CommandLineParser.ParseArguments(args, a);
모두가 자신의 애완 동물 명령 줄 파서를 가지고있는 것처럼 보입니다.
이 라이브러리에는 명령 줄 의 값으로 클래스를 초기화 하는 명령 줄 파서 가 포함되어 있습니다 . 그것은 많은 기능을 가지고 있습니다 (수년 동안 그것을 구축해 왔습니다).
로부터 문서 ...
BizArk 프레임 워크의 명령 줄 구문 분석에는 다음과 같은 주요 기능이 있습니다.
나는 C # 명령 줄 인수 파서를 잠시 썼다. 그것에서 : http://www.codeplex.com/CommandLineArguments
CLAP (명령 줄 인수 파서)에는 유용한 API가 있으며 훌륭하게 문서화되어 있습니다. 매개 변수에 주석을 달아 메소드를 작성합니다. https://github.com/adrianaisemberg/CLAP
myapp myverb -argname argvalue
(필수 -argname
) 또는 myapp -help
(보통 --help
).
이 문제에 대한 수많은 해결책이 있습니다. 완전성을 원하고 누군가가 원하는 경우 대안을 제공하기 위해 Google 코드 라이브러리 에 두 가지 유용한 클래스에 대한 답변을 추가하고 있습니다 .
첫 번째는 ArgumentList이며 명령 행 매개 변수 구문 분석 만 담당합니다. 스위치 '/ x : y'또는 '-x = y'에 의해 정의 된 이름-값 쌍을 수집하고 '명명되지 않은'항목의 목록도 수집합니다. 기본적인 사용법은 여기 에서 설명 합니다 . 여기에서 클래스를보십시오 .
두 번째 부분은 CommandInterpreter 로 .Net 클래스에서 완전한 기능을 갖춘 명령 줄 응용 프로그램을 만듭니다. 예로서:
using CSharpTest.Net.Commands;
static class Program
{
static void Main(string[] args)
{
new CommandInterpreter(new Commands()).Run(args);
}
//example ‘Commands’ class:
class Commands
{
public int SomeValue { get; set; }
public void DoSomething(string svalue, int ivalue)
{ ... }
위의 예제 코드를 사용하면 다음을 실행할 수 있습니다.
Program.exe DoSomething "문자열 값"5
-또는-
Program.exe dosomething / ivalue = 5 -svalue : "문자열 값"
간단하거나 필요에 따라 복잡합니다. 당신은 수있는 소스 코드를 검토 , 도움을 보거나 , 또는 바이너리를 다운로드 .
나는 당신이 필요 여부에 관계없이 인수에 대한 규칙을 정의 할 수 있기 때문에 그 중 하나를 좋아 합니다 ...
또는 유닉스 사용자라면 GNU Getopt .NET 포트를 좋아할 것 입니다.
당신은 내 하나의 러그를 좋아할 것입니다.
사용하기 쉽고 확장 가능한 명령 줄 인수 파서. 처리 : 부울, 플러스 / 마이너스, 문자열, 문자열 목록, CSV, 열거.
'/?'내장 도움말 모드.
'/ ??'내장 및 '/? D'문서 생성기 모드.
static void Main(string[] args)
{
// create the argument parser
ArgumentParser parser = new ArgumentParser("ArgumentExample", "Example of argument parsing");
// create the argument for a string
StringArgument StringArg = new StringArgument("String", "Example string argument", "This argument demonstrates string arguments");
// add the argument to the parser
parser.Add("/", "String", StringArg);
// parse arguemnts
parser.Parse(args);
// did the parser detect a /? argument
if (parser.HelpMode == false)
{
// was the string argument defined
if (StringArg.Defined == true)
{
// write its value
RC.WriteLine("String argument was defined");
RC.WriteLine(StringArg.Value);
}
}
}
편집 : 이것은 내 프로젝트 이므로이 답변은 타사의 추천으로 보아서는 안됩니다. 그것은 내가 작성한 모든 명령 줄 기반 프로그램에 사용한다고 말했지만 오픈 소스이며 다른 사람들이 혜택을 볼 수 있기를 바랍니다.
http://www.codeplex.com/commonlibrarynet에 명령 행 인수 구문 분석기가 있습니다 .
1을 사용하여 인수를 구문 분석 할 수 있습니다 .
2. 명시 적 호출
3. 여러 인수의 단일 행 또는 문자열 배열
다음과 같은 것을 처리 할 수 있습니다.
- 설정 : Qa- 시작일 : $ { 오늘 }- 지역 : '뉴욕'설정 01
사용하기 매우 쉽습니다.
이것은 Novell Options
클래스를 기반으로 작성한 처리기 입니다.
이것은 while (input !="exit")
FTP 루프와 같은 대화식 콘솔 인 스타일 루프 를 실행하는 콘솔 응용 프로그램을 대상 으로합니다.
사용법 예 :
static void Main(string[] args)
{
// Setup
CommandHandler handler = new CommandHandler();
CommandOptions options = new CommandOptions();
// Add some commands. Use the v syntax for passing arguments
options.Add("show", handler.Show)
.Add("connect", v => handler.Connect(v))
.Add("dir", handler.Dir);
// Read lines
System.Console.Write(">");
string input = System.Console.ReadLine();
while (input != "quit" && input != "exit")
{
if (input == "cls" || input == "clear")
{
System.Console.Clear();
}
else
{
if (!string.IsNullOrEmpty(input))
{
if (options.Parse(input))
{
System.Console.WriteLine(handler.OutputMessage);
}
else
{
System.Console.WriteLine("I didn't understand that command");
}
}
}
System.Console.Write(">");
input = System.Console.ReadLine();
}
}
그리고 출처 :
/// <summary>
/// A class for parsing commands inside a tool. Based on Novell Options class (http://www.ndesk.org/Options).
/// </summary>
public class CommandOptions
{
private Dictionary<string, Action<string[]>> _actions;
private Dictionary<string, Action> _actionsNoParams;
/// <summary>
/// Initializes a new instance of the <see cref="CommandOptions"/> class.
/// </summary>
public CommandOptions()
{
_actions = new Dictionary<string, Action<string[]>>();
_actionsNoParams = new Dictionary<string, Action>();
}
/// <summary>
/// Adds a command option and an action to perform when the command is found.
/// </summary>
/// <param name="name">The name of the command.</param>
/// <param name="action">An action delegate</param>
/// <returns>The current CommandOptions instance.</returns>
public CommandOptions Add(string name, Action action)
{
_actionsNoParams.Add(name, action);
return this;
}
/// <summary>
/// Adds a command option and an action (with parameter) to perform when the command is found.
/// </summary>
/// <param name="name">The name of the command.</param>
/// <param name="action">An action delegate that has one parameter - string[] args.</param>
/// <returns>The current CommandOptions instance.</returns>
public CommandOptions Add(string name, Action<string[]> action)
{
_actions.Add(name, action);
return this;
}
/// <summary>
/// Parses the text command and calls any actions associated with the command.
/// </summary>
/// <param name="command">The text command, e.g "show databases"</param>
public bool Parse(string command)
{
if (command.IndexOf(" ") == -1)
{
// No params
foreach (string key in _actionsNoParams.Keys)
{
if (command == key)
{
_actionsNoParams[key].Invoke();
return true;
}
}
}
else
{
// Params
foreach (string key in _actions.Keys)
{
if (command.StartsWith(key) && command.Length > key.Length)
{
string options = command.Substring(key.Length);
options = options.Trim();
string[] parts = options.Split(' ');
_actions[key].Invoke(parts);
return true;
}
}
}
return false;
}
}
내가 가장 좋아하는 것은 Peter Palotas의 http://www.codeproject.com/KB/recipes/plossum_commandline.aspx입니다 .
[CommandLineManager(ApplicationName="Hello World",
Copyright="Copyright (c) Peter Palotas")]
class Options
{
[CommandLineOption(Description="Displays this help text")]
public bool Help = false;
[CommandLineOption(Description = "Specifies the input file", MinOccurs=1)]
public string Name
{
get { return mName; }
set
{
if (String.IsNullOrEmpty(value))
throw new InvalidOptionValueException(
"The name must not be empty", false);
mName = value;
}
}
private string mName;
}
최근에 FubuCore Command line 구문 분석 구현이 마음에 들었습니다. 그 이유는 다음과 같습니다.
아래는 이것을 사용하는 간단한 예입니다. 사용법을 설명하기 위해 두 가지 명령이있는 간단한 유틸리티를 작성했습니다. 현재 추가 된 모든 객체)
먼저 'add'명령에 대한 Command 클래스를 작성했습니다.
[Usage("add", "Adds an object to the list")]
[CommandDescription("Add object", Name = "add")]
public class AddCommand : FubuCommand<CommandInput>
{
public override bool Execute(CommandInput input)
{
State.Objects.Add(input); // add the new object to an in-memory collection
return true;
}
}
이 명령은 CommandInput 인스턴스를 매개 변수로 사용하므로 다음을 정의합니다.
public class CommandInput
{
[RequiredUsage("add"), Description("The name of the object to add")]
public string ObjectName { get; set; }
[ValidUsage("add")]
[Description("The value of the object to add")]
public int ObjectValue { get; set; }
[Description("Multiply the value by -1")]
[ValidUsage("add")]
[FlagAlias("nv")]
public bool NegateValueFlag { get; set; }
}
다음 명령은 'list'이며 다음과 같이 구현됩니다.
[Usage("list", "List the objects we have so far")]
[CommandDescription("List objects", Name = "list")]
public class ListCommand : FubuCommand<NullInput>
{
public override bool Execute(NullInput input)
{
State.Objects.ForEach(Console.WriteLine);
return false;
}
}
'list'명령은 매개 변수를 사용하지 않으므로 NullInput 클래스를 정의했습니다.
public class NullInput { }
이제 남은 것은 Main () 메소드에서 이것을 다음과 같이 연결하는 것입니다.
static void Main(string[] args)
{
var factory = new CommandFactory();
factory.RegisterCommands(typeof(Program).Assembly);
var executor = new CommandExecutor(factory);
executor.Execute(args);
}
명령이 유효하지 않은 경우 올바른 사용법에 대한 힌트를 인쇄하여 프로그램이 예상대로 작동합니다.
------------------------
Available commands:
------------------------
add -> Add object
list -> List objects
------------------------
'add'명령의 샘플 사용법은 다음과 같습니다.
Usages for 'add' (Add object)
add <objectname> [-nv]
-------------------------------------------------
Arguments
-------------------------------------------------
objectname -> The name of the object to add
objectvalue -> The value of the object to add
-------------------------------------------------
-------------------------------------
Flags
-------------------------------------
[-nv] -> Multiply the value by -1
-------------------------------------
파워 쉘 커맨드 렛.
커맨드 렛에 지정된 속성, 유효성 검사, 매개 변수 세트, 파이프 라이닝, 오류보고, 도움말 및 다른 커맨드 렛에서 사용하기 위해 반환되는 모든 .NET 객체 중 최고를 기반으로 Powershell이 구문 분석을 수행합니다.
시작하는 데 도움이되는 링크 몇 개 :
징 기스 커맨드 라인 파서 는 구식 일 수도 있지만, 기능이 매우 완벽하고 나에게 잘 작동합니다.
오픈 소스 라이브러리 CSharpOptParse를 제안합니다 . 명령 행을 구문 분석하고 명령 행 입력으로 사용자 정의 .NET 오브젝트를 수화합니다. C # 콘솔 응용 프로그램을 작성할 때는 항상이 라이브러리를 사용합니다.
Apache Commons CLI API의 .net 포트를 사용하십시오. 이것은 잘 작동합니다.
http://sourceforge.net/projects/dotnetcli/
개념 및 소개를위한 원래 API
기본 인수를 지원하는 명령 줄 구문 분석을위한 매우 간단한 사용하기 쉬운 임시 클래스입니다.
class CommandLineArgs
{
public static CommandLineArgs I
{
get
{
return m_instance;
}
}
public string argAsString( string argName )
{
if (m_args.ContainsKey(argName)) {
return m_args[argName];
}
else return "";
}
public long argAsLong(string argName)
{
if (m_args.ContainsKey(argName))
{
return Convert.ToInt64(m_args[argName]);
}
else return 0;
}
public double argAsDouble(string argName)
{
if (m_args.ContainsKey(argName))
{
return Convert.ToDouble(m_args[argName]);
}
else return 0;
}
public void parseArgs(string[] args, string defaultArgs )
{
m_args = new Dictionary<string, string>();
parseDefaults(defaultArgs );
foreach (string arg in args)
{
string[] words = arg.Split('=');
m_args[words[0]] = words[1];
}
}
private void parseDefaults(string defaultArgs )
{
if ( defaultArgs == "" ) return;
string[] args = defaultArgs.Split(';');
foreach (string arg in args)
{
string[] words = arg.Split('=');
m_args[words[0]] = words[1];
}
}
private Dictionary<string, string> m_args = null;
static readonly CommandLineArgs m_instance = new CommandLineArgs();
}
class Program
{
static void Main(string[] args)
{
CommandLineArgs.I.parseArgs(args, "myStringArg=defaultVal;someLong=12");
Console.WriteLine("Arg myStringArg : '{0}' ", CommandLineArgs.I.argAsString("myStringArg"));
Console.WriteLine("Arg someLong : '{0}' ", CommandLineArgs.I.argAsLong("someLong"));
}
}