蚂蚁:如何在目录中的每个文件执行命令?(Ant: How to execute a command

2019-07-19 04:56发布

我想从一个Ant构建执行命令,对目录中的每个文件。
我找了一个独立于平台的解决方案。

我该怎么做呢?

当然,我可以写一些脚本语言的脚本,但是这将进一步增加依赖于该项目。

Answer 1:

简答

使用<foreach>具有嵌套<FileSet>

的foreach需要蚂蚁的contrib 。

近期蚂蚁的contrib更新了例:

<target name="foo">
  <foreach target="bar" param="theFile">
    <fileset dir="${server.src}" casesensitive="yes">
      <include name="**/*.java"/>
      <exclude name="**/*Test*"/>
    </fileset>
  </foreach>
</target>

<target name="bar">
  <echo message="${theFile}"/>
</target>

这将antcall目标“栏”与$ {} theFile导致当前文件。



Answer 2:

使用<应用>任务 。

它执行一个命令一次为每个文件。 通过集或任何其他资源的手段指定的文件。 <应用>是内置的; 没有额外的依赖性需要; 没有自定义任务的实现需要。

它也可以只运行一次命令,附加的所有文件作为变量,一气呵成。 使用并行属性切换行为。

对不起,我迟到了一年。



Answer 3:

没有蚂蚁的contrib的方法是通过提出塔西洛霍恩 (在原来的目标是在这里 )

基本上,因为不存在扩展的<java的>在于:所述相同的方式(没有?) <应用>延伸<EXEC>时,他建议使用<申请>(其当然也可以在命令行运行Java PROGRAMM)

这里是一些例子:

  <apply executable="java"> 
    <arg value="-cp"/> 
    <arg pathref="classpath"/> 
    <arg value="-f"/> 
    <srcfile/> 
    <arg line="-o ${output.dir}"/> 

    <fileset dir="${input.dir}" includes="*.txt"/> 
  </apply> 


Answer 4:

这里是办法做到这一点使用JavaScript和蚂蚁scriptdef任务,你不需要蚂蚁的contrib这个代码工作,因为scriptdef是核心ant任务。

<scriptdef name="bzip2-files" language="javascript">
<element name="fileset" type="fileset"/>
<![CDATA[
  importClass(java.io.File);
  filesets = elements.get("fileset");

  for (i = 0; i < filesets.size(); ++i) {
    fileset = filesets.get(i);
    scanner = fileset.getDirectoryScanner(project);
    scanner.scan();
    files = scanner.getIncludedFiles();
    for( j=0; j < files.length; j++) {

        var basedir  = fileset.getDir(project);
        var filename = files[j];
        var src = new File(basedir, filename);
        var dest= new File(basedir, filename + ".bz2");

        bzip2 = self.project.createTask("bzip2");        
        bzip2.setSrc( src);
        bzip2.setDestfile(dest ); 
        bzip2.execute();
    }
  }
]]>
</scriptdef>

<bzip2-files>
    <fileset id="test" dir="upstream/classpath/jars/development">
            <include name="**/*.jar" />
    </fileset>
</bzip2-files>


Answer 5:

蚂蚁的contrib是邪恶的; 编写定制Ant任务。

蚂蚁的contrib是邪恶的,因为它试图蚂蚁从声明的风格转换势在必行的风格。 但是XML是一个废话编程语言。

相比之下定制ant任务可以让你在真实的语言(Java)的编写,与真正的IDE,在那里你可以编写单元测试,以确保你有你想要的行为,然后使你的构建脚本干净声明你想要的行为。

如果你关心编写可维护的Ant脚本,这咆哮仅事项。 如果你不关心用一切手段维护做什么工作的。 :)

JTF



Answer 6:

我知道这个帖子是真的老了,但现在一些时间和蚂蚁的版本通过,有一种方法与基本蚁群功能做到这一点,我想我应该分享。

它是通过调用嵌套任务的递归macrodef完成(甚至其他的宏可以被调用)。 唯一的约定是使用固定的变量名(元素在这里)。

<project name="iteration-test" default="execute" xmlns="antlib:org.apache.tools.ant" xmlns:if="ant:if" xmlns:unless="ant:unless">

    <macrodef name="iterate">
        <attribute name="list" />
        <element name="call" implicit="yes" />
        <sequential>
            <local name="element" />
            <local name="tail" />
            <local name="hasMoreElements" />
            <!-- unless to not get a error on empty lists -->
            <loadresource property="element" unless:blank="@{list}" >
                <concat>@{list}</concat>
                <filterchain>
                    <replaceregex pattern="([^;]*).*" replace="\1" />
                </filterchain>
            </loadresource>
            <!-- call the tasks that handle the element -->
            <call />

            <!-- recursion -->
            <condition property="hasMoreElements">
                <contains string="@{list}" substring=";" />
            </condition>

            <loadresource property="tail" if:true="${hasMoreElements}">
                <concat>@{list}</concat>
                <filterchain>
                    <replaceregex pattern="[^;]*;(.*)" replace="\1" />
                </filterchain>
            </loadresource>

            <iterate list="${tail}" if:true="${hasMoreElements}">
                <call />
            </iterate>
        </sequential>
    </macrodef>

    <target name="execute">
        <fileset id="artifacts.fs" dir="build/lib">
            <include name="*.jar" />
            <include name="*.war" />
        </fileset>

        <pathconvert refid="artifacts.fs" property="artifacts.str" />

        <echo message="$${artifacts.str}: ${artifacts.str}" />
        <!-- unless is required for empty lists to not call the enclosed tasks -->
        <iterate list="${artifacts.str}" unless:blank="${artifacts.str}">
            <echo message="I see:" />
            <echo message="${element}" />
        </iterate>
        <!-- local variable is now empty -->
        <echo message="${element}" />
    </target>
</project>

所需的关键特性,其中:

  • http://ant.apache.org/manual/ifunless.html在蚂蚁1.9.1引入(学分蚂蚁条件如果macrodef内 )
  • 子,非常感谢如何拔出子的蚂蚁
  • 内联macrodef元件。

我没有管理,使分隔符variabel,但是这可能不是一个主要缺点。



Answer 7:

您可以使用ant-的contrib任务“”遍历文件列表上的任何分隔符分开,默认定界符“”。

以下是这说明这个示例文件:

<project name="modify-files" default="main" basedir=".">
    <taskdef resource="net/sf/antcontrib/antlib.xml"/>
    <target name="main">
        <for list="FileA,FileB,FileC,FileD,FileE" param="file">
          <sequential>
            <echo>Updating file: @{file}</echo>
            <!-- Do something with file here -->
          </sequential>
        </for>                         
    </target>
</project>


Answer 8:

做blak3r建议什么,定义你的目标classpath中,像这样

<taskdef resource="net/sf/antcontrib/antlib.xml">
    <classpath>
        <fileset dir="lib">
          <include name="**/*.jar"/>
        </fileset>
    </classpath>        
</taskdef>

其中lib是存储你的罐子的



文章来源: Ant: How to execute a command for each file in directory?