我有一个包含多个值的属性,我想为该属性中的每个值执行一个带有单独"-j"参数的命令。
例如<property name="arguments" value="foo bar hello world"/>
应该执行:mycommand-jfoo-jbar-jhello-jworld
我使用的是Ant 1.7.1,所以不能在<exec>
任务的<arg>
元素上使用"prefix"属性(Ant 1.8)。
一种解决方法是手动将"-j"直接插入到属性中,然后使用<arg>
:的"line"属性
<property name="args" value="-j foo -j bar -j hello -j world"/>
<exec executable="mycommand">
<arg line="${args}"/>
</exec>
但我更希望属性是一个没有嵌入参数的简单列表。
编辑:实际上,我的参数是XML文件中的路径,所以更准确的参数列表应该是:
<property name="arguments" value="/foo/bar /hello/world /a/very/long/path"/>
我希望该命令然后用参数执行:"-j/foo/bar-j/hello/world-j/a/veri/long/path"。请注意,即使在Windows下,斜杠仍然是正斜杠(这些是命令的参数,而不是文件名)。
您可以使用Ant资源工具来实现这一点。
<property name="arg_list" value="foo bar hello world"/>
<resources id="arguments">
<mappedresources>
<string value="${arg_list}" />
<filtermapper>
<replacestring from=" " to=" -j "/>
</filtermapper>
</mappedresources>
</resources>
<property name="arguments" value="-j ${toString:arguments}" />
以上将导致属性arguments
具有值-j foo -j bar -j hello -j world
,然后可以在exec
arg
行中使用该值。
或者,pathconvert
任务可以在这方面有所帮助:
<property name="arg_list" value="foo bar hello world"/>
<pathconvert property="arguments" pathsep=" ">
<chainedmapper>
<flattenmapper />
<regexpmapper from="(.*)" to="-j 1" />
</chainedmapper>
<filelist files="${arg_list}" />
</pathconvert>
如果您有绝对路径,而不仅仅是列表中的字符串,则删除flattenmapper
。
如果您有相对路径,请将flattenmapper
行替换为:
<globmapper from="${basedir}/*" to="*" />
以防止路径被转换为绝对路径。
如果在Windows系统的arg_list中有类似UNIX的路径,则pathconvert的默认设置将不起作用——路径将转换为Windows样式。相反,要处理列表,请使用:
<pathconvert property="arguments" pathsep=" " targetos="unix">
<chainedmapper>
<regexpmapper from="C:(.*)" to="-j 1" />
</chainedmapper>
<filelist files="${arg_list}" />
</pathconvert>
注意参数中的targetos
设置和修订的regexmapper。
使用some for循环,这里有一个基于Ant的解决方案Addon Flaka:
<project name="demo" xmlns:fl="antlib:it.haefelinger.flaka">
<!-- make standard ant tasks like i.e. exec understand EL expressions -->
<fl:install-property-handler/>
<property name="arguments" value="foo bar hello world"/>
<fl:for var="arg" in="split('${arguments}',' ')">
<exec executable="mycommand">
<arg line="#{arg} -j"/>
</exec>
</fl:for>
</project>
不确定您对脚本语言是否满意,但您也可以嵌入脚本来进行解析/重组:
http://ant.apache.org/manual/Tasks/script.html
我会说,我认为它有点脆弱,因为你明确提到了ANT项目的名称,但取决于你:
<?xml version="1.0" encoding="utf-8"?>
<project name="ScriptProj" basedir=".">
<property name="arguments" value="foo bar hello world"/>
<target name="test">
<script language="javascript">
<![CDATA[
argsParm = ScriptProj.getProperty("arguments");
argsParmAmend = "";
args = argsParm.split(" ");
for (i = 0; i < args.length; i++)
argsParmAmend = argsParmAmend + "-j " + args[i] + " ";
// remove trailing string
ScriptProj.setProperty("arguments.amended", argsParmAmend.substr(0, argsParmAmend.length-1));
]]>
</script>
<echo>${arguments}</echo>
<echo>${arguments.amended}</echo>
</target>
</project>