groovy sed错误sed:-e expression#1,char 1:unknown命令:`''

时间:2018-01-04 09:29:06

标签: groovy sed

Groovy代码是:

def cmd = "sed -i \'1 i <?xml version=\"1.1\"?>\' test.xml"
println cmd
println cmd.execute().err.text

输出:

sed -i '1 i <?xml version="1.1"?>' test.xml
sed: -e expression #1, char 1: unknown command: `''

这是在cli中运行良好的实际命令sed -i '1 i <?xml version="1.1"?>' test.xml。但Groovy execute()无法正常工作。如何解决这个问题?

更新1:

还尝试使用以下cmd,但仍显示相同的错误。

def cmd = /sed -i '1 i <?xml version="1.1"?>' test.xml/
def cmd = "sed -i '1 i <?xml version=\"1.1\"?>' test.xml"

更新注意:

检查和更新xml文件,

def insertversion(String filename)
{
    def lines= new File (filename).readLines()
    if(!(lines.get(0)).contains('xml version'))
    {
        def cmd = ['sed', '-i', '1 i <?xml version="1.1"?>', filename]
        cmd.execute()
    }
}

1 个答案:

答案 0 :(得分:3)

在这种情况下,执行shell命令作为cmd和参数的列表,而不是执行命令为String:

def cmd = ['sed', '-i', '1 i <?xml version="1.1"?>', 'test.xml']
println cmd
println cmd.execute().err.text

在运行脚本后,此部分<?xml version="1.1">test.xml文件中重复(与从命令行运行给定命令的行为相同)。

List.execute()String.execute()之间的区别是什么?

如果以字符串形式执行shell命令,java.lang.Runtime.exec()方法将使用java.util.StringTokenizer将输入字符串拆分为数组。在您的情况下,tokenizer将创建7个令牌,您可以通过运行以下脚本来检查它:

def cmd = "sed -i \'1 i <?xml version=\"1.1\"?>\' test.xml"

def tokenizer = new StringTokenizer(cmd)
def tokens = []
while (tokenizer.hasMoreTokens()) {
    tokens << tokenizer.nextToken()
}

tokens.each { println it }

输出:

sed
-i
'1
i
<?xml
version="1.1"?>'
test.xml

您还可以通过运行调试器来验证它,并在第96行的java.lang.Runtime类中设置检查点:

enter image description here

这当然是不正确的。使用列表执行shell命令时,我们将获得正确的命令行参数数组:

enter image description here

一般的经验法则是,如果你的shell命令包含可能会混淆java.util.StringTokenizer的字符,最好使用列表来定义正确的命令行参数列表。