删除与另一个目录树中的占位符匹配的文件

时间:2012-04-17 20:38:04

标签: ant

我有两个目录树:

source/aaa/bbb/ccc/file01.txt
source/aaa/bbb/file02.txt
source/aaa/bbb/file03.txt
source/aaa/ddd/file03.txt
source/file01.txt

template/aaa/bbb/ccc/file01.txt
template/aaa/bbb/DELETE-file03.txt
template/aaa/DELETE-ddd
template/DELETE-file01.txt

使用Ant,我想做三件事。首先,我想将“template”中的任何文件复制到“source”中,以便替换所有不以“DELETE-”开头的文件。例如,“source / aaa / bbb / ccc / file01.txt”将被替换。这很简单:

<copy todir="source" verbose="true" overwrite="true">
    <fileset dir="template">
        <exclude name="**/DELETE-*"/>
    </fileset>
</copy>

其次,我想删除“source”树中名称与“template”树的相应目录中的“DELETE-”文件匹配的所有文件。例如,将删除“source / aaa / bbb / file03.txt”和“source / file01.txt”。我已经能够通过以下方式实现这一目标:

<delete verbose="true">
    <fileset dir="source">
        <present present="both" targetdir="template">
            <mapper type="regexp" from="(.*[/\\])?([^/\\]+)" to="\1DELETE-\2"/>
        </present>
    </fileset>
</delete>   

第三,我想以相同的方式删除名称匹配的任何目录(空或不)。例如,“template / aaa / DELETE-ddd”及其下的所有文件都将被删除。我不确定如何在“source”树中构建一个匹配目录(及其下的所有文件)的文件集,其中目录在“template”树中有一个DELETE- *文件。

Ant(1.7.1)的第三项任务是否可行?我最好不要编写任何自定义的ant任务/选择器。

2 个答案:

答案 0 :(得分:1)

似乎根本问题使得难以根据文件集的目标目录中找到的文件来驱动选择器/文件集。但是,通常情况下,人们会想要从DELETE- *标记文件列表中驱动东西。

到目前为止我找到的最佳解决方案确实需要一些自定义代码。我选择了<groovy>任务,但也可以使用<script>

要点:创建一个文件集,使用groovy添加一系列使用DELETE- *标记跳过文件和目录的排除项,然后执行复制。这完成了我的第二和第三项任务。

<fileset id="source_files" dir="source"/>

<!-- add exclude patterns to fileset that will skip any files with a DELETE-* marker -->
<groovy><![CDATA[
    def excludes = []
    new File( "template" ).eachFileRecurse(){ File templateFile ->
        if( templateFile.name =~ /DELETE-*/ ){
            // file path relative to template dir
            def relativeFile = templateFile.toString().substring( "template".length() )
            // filename with DELETE- prefix removed
            def withoutPrefix = relativeFile.replaceFirst( "DELETE-", "")
            // add wildcard to match all files under directories
            def exclude = withoutPrefix + "/**"
            excludes << exclude
        }
    }
    def fileSet = project.getReference("source_files")
    fileSet.appendExcludes(excludes as String[])
]]></groovy>

<!-- create a baseline copy, excluding files with DELETE-* markers in the template directories -->
<copy todir="target">
    <fileset refid="source_files"/>
</copy>

答案 1 :(得分:0)

要删除目录及其内容,请使用delete with nested fileset,即:

 <delete includeemptydirs="true">
  <fileset dir="your/root/directory" defaultexcludes="false">
   <include name="**/DELETE-*/**" />
  </fileset>
 </delete>

使用属性includeemptydirs="true",目录也将被删除。