如何在 NIM 中通过命令行正确传递参数?

How to properly pass arguments via command line in NIM?

我正在使用以下代码片段来解析命令行参数并将它们存储在 table.

var args = initTable[string, string]()
for kind, key, val in getopt():
    args.add(key,val)

但是,只有当我在命令行中传递 = 时它才有效

./mytool -i=somefile.txt

在这种情况下,args 就是 {i: somefile.txt},这就是我想要的(一对 key:value)。

但如果我使用 ./mytool -i somefile.txt,那么 args 就是 {somefile.txt: , i: },这绝对不是我所期望的(两个键,没有值)。

不使用 = 解析参数的正确方法是什么?

这里是两种情况下kind,key,val的打印输出:

$ ./diceof -a=ACTGCTGTGTGCACAGTGTCACGTGT -b=ACTGCTGTGTGCACAGTGTCACGTGa
kind:cmdShortOption
key :a
val :ACTGCTGTGTGCACAGTGTCACGTGT
kind:cmdShortOption
key :b
val :ACTGCTGTGTGCACAGTGTCACGTGa


$ ./diceof -a ACTGCTGTGTGCACAGTGTCACGTGT -b ACTGCTGTGTGCACAGTGTCACGTGa
kind:cmdShortOption
key :a
val :
kind:cmdArgument
key :ACTGCTGTGTGCACAGTGTCACGTGT
val :
kind:cmdShortOption
key :b
val :
kind:cmdArgument
key :ACTGCTGTGTGCACAGTGTCACGTGa
val :

当然,我可以检查是否找到 val,如果没有,则将下一个 key 添加为前一个的 val。但我正在寻找更优雅的解决方案。

基于 documentation for parseopt2 and the discussion in commandeer 的问题(参见#10),parseopt2 只能使用 =: 为键设置值,除此之外我不会知道是否有 'proper' 方法来解析选项值。

Commandeer 通过检查下一个标记是否为 cmdArgument 并分配值来处理键和值由 space 分隔的选项。

var nextToken = cliTokens.pop()
if nextToken.kind == parseopt2.cmdArgument:
  try:
    assign(nextToken.key)
  except ValueError:
    exitWithErrorMessage(getCurrentExceptionMsg())
  else:
    cliTokens.add(nextToken)

argparse好像是唯一的Nim包,终于支持POSIX风格的参数解析,自动形成app帮助(用法)文本:

$ ./example -c=settings.cfg 
Parsed opts: (config: "settings.cfg", help: false)

$ ./example -c settings.cfg 
Parsed opts: (config: "settings.cfg", help: false)

$ ./example -h
example

Usage:
  example [options] 

Options:
  -c, --config=CONFIG        Configuration file
  -h, --help                 Show this help
Parsed opts: (config: "", help: true)

来源:

import argparse

let p = newParser("example"):
  option("-c", "--config", help="Configuration file")
echo("Parsed opts: ", p.parse(commandLineParams()))