【问题标题】:How can i use asterisk(*) in command line arguments in groovy?如何在 groovy 的命令行参数中使用星号(*)?
【发布时间】:2017-02-10 12:00:57
【问题描述】:

喂!

我有一个带有一个参数的 groovy 脚本。参数必须是正则表达式模式。我想在参数中使用 *,但总是得到:命令的语法不正确。

这是一个例子(opt.p 是从 arg 得到的模式):

    def map1 = [e:'pine___apple', f:'pineapple']
    map1.each { entry ->
                entry.value.find(~/$opt.p/) { match -> println entry.value}
                }

我想以这种方式从命令行使用脚本:

常规测试 -p pine_*a

我希望结果是:

松___苹果
菠萝

我尝试了这些解决方案等等,但没有任何效果:
pine_*a
"pine_*a"
'pine_*a'
pine_\*a
'pine_\*a'
"pine_\*a"
pine_'\*'a
pine_"\*"a
pine_'\\*'a
pine_"\\*"a

有人知道如何解决这个问题吗? 非常感谢!

编辑:
我使用:
Groovy 版本:2.4.6 JVM:1.7.0_45 供应商:Oracle Corporation 操作系统:Windows 7
我也使用 CliBuilder:

def cli = new CliBuilder()
        cli.with
        {
            p('pattern', args: 1, required: false)
        }   
        def opt = cli.parse(args)

【问题讨论】:

  • 你为什么认为opt.p有你的论点?您的 groovy 中是否有一些设置此变量的代码?尝试打印 opt.p 以查看其中包含的内容。
  • 如果该值未加引号,您将受制于 shell 替换文件名。例如:touch pine_fooled_ya; groovy test -p pine_*a。传递正则表达式最安全的方法是使用单引号:groovy test -p 'pine_*a'

标签: regex groovy command-line arguments syntax-error


【解决方案1】:

以下 groovy 脚本:

def map = [e:'pine___apple', f:'pineapple']
map.each { k, v ->
  v.find(~/${args[0]}/) { println "key: $k, value: $v -> ${v.find(args[0])}" }
}

在调用时打印以下内容:

$ groovy test.groovy pine_*a
Checking key: e, value: pine___apple -> pine___a
Checking key: f, value: pineapple -> pinea

或排除其中一个地图条目:

$ groovy test.groovy "pine_{1,9}a"
key: e, value: pine___apple -> pine___a

不确定您的脚本有什么问题。也许像其中一个 cmets 所暗示的那样处理 opts.p 。

编辑 1

Tim Yates 在回答中提到的另一种 CliBuilder 语法:

def opt = new CliBuilder().with {
    p longOpt: 'pattern', args: 1
    parse(args)
} 

编辑 2:解决方案

因为这被标记为已接受的答案,所以我将在此处添加最终成为解决方案的内容(我在下面对此有评论,但在浏览解决方案时 cmets 并不立即显而易见)。

这个问题是由用于启动 groovy 的 windows groovy 发行版 startgroovy.bat 文件 (see separate stackoverflow thread) 中的错误引起的。问题在于 Windows 执行和参数处理,它发生在 groovy 程序甚至开始执行之前。在 groovy 的更高版本中很有可能已修复此问题,因此可能值得尝试升级到最新版本。如果没有,上述线程中的答案应该可以修复startgroovy.bat

【讨论】:

  • 我尝试了您的示例,并且使用“pine_{1,9}a”arg 我得到了与您相同的结果,但是 pine_*a 对我不起作用。我仍然遇到我之前提到的语法错误。我真的不知道是什么问题。我在上面编辑了我的问题,我如何使用 CliBuilder 以及使用哪个 groovy 版本。任何其他想法可能是什么问题?
  • 你能尝试引用groovy test.groovy "ping_*a"吗?
  • 我试过了。仍然有语法错误。 test.groovy "pine_{1,9}a" 可以正常工作并获得与您相同的结果,但 groovy test.groovy "ping_*a" 出现语法错误。
  • 根据之前的评论,根据您使用的操作系统,可能还值得尝试使用单引号。您是否也可以在您的 entry.value.find 之前执行 entry -> def val = /$p.opt/;println "value is: '$val' ,以便我们可以验证 opt.p 的值是我们认为的值。
  • 好的。所以结果是:C:\Users>groovy test.groovy -p "pine_?"value is: pine_?pine___applevalue is: pine_?pineappleC:\Users>groovy test.groovy -p 'pine_?'value is: 'pine_?'value is: 'pine_?'value is: 'pine_?'value is: 'pine_?'C:\Users>groovy test.groovy -p 'pine_*'The syntax of the command is incorrect.@98765434@43C:\Users>groovy test.groovy -p "pine_*"pan
【解决方案2】:

认为这是您捕获 opt 的方式

我假设您正在使用 CliBuilder

我怀疑你错过了p参数定义中的args: 1

def opt = new CliBuilder().with {
    it.p('pattern', args: 1)
    parse(args)
}  

def map1 = [e:'pine___apple', f:'pineapple']
map1.each { entry ->
    entry.value.find(~/$opt.p/) { match -> println entry.value}
}

按你描述的那样工作……

【讨论】:

  • 是的。我使用 CliBuilder,我也使用 args:1。我试过你的例子,不适合我。我仍然遇到我之前提到的语法错误。我真的不知道是什么问题。我在上面编辑了我的问题,我如何使用 CliBuilder 以及使用哪个 groovy 版本。任何其他想法可能是什么问题?
猜你喜欢
  • 2015-01-01
  • 1970-01-01
  • 2014-09-06
  • 1970-01-01
  • 1970-01-01
  • 2015-06-02
  • 1970-01-01
  • 1970-01-01
  • 2020-12-04
相关资源
最近更新 更多