【问题标题】:Ant Rename files maintaining directory structureAnt 重命名文件维护目录结构
【发布时间】:2015-10-05 12:29:40
【问题描述】:

我想使用 Ant 重命名文件,维护它们的目录结构。

例如假设以下目录结构:

- copy
    - new
        - testthis.a

使用下面的代码,我可以使用复制任务将包含“this”单词的文件重命名为“that.a”,但它们都被粘贴到“paste”目录中,失去了目录结构。

<copy todir="paste" overwrite="true">
    <fileset dir="copy"/>
    <regexpmapper from="^(.*)this(.*)\.a$$" to="that.a"/>
</copy>

输出:

- paste
    - that.a

如果我将 regexmapper 更改为(注意之前的 \1.a):

    <regexpmapper from="^(.*)this(.*)\.a$$" to="\1that.a"/>

它会生成正确的目录结构,但总是将“this”之前的单词添加到“that.a”

输出:

- paste
    - new
        - testthat.a

有没有什么方法可以重命名文件以保持其目录结构而无需预先或附加任何单词?

还有其他的映射器可以用来做同样的事情吗?

任何帮助将不胜感激。

【问题讨论】:

    标签: ant


    【解决方案1】:
    <copy todir="paste" verbose="true">
        <fileset dir="copy" includes="**/*this*.a"/>
        <regexpmapper from="((?:[^/]+/)*)[^/]+$$" to="\1that.a" handledirsep="true"/>
    </copy>
    

    首先,设置handledirsep="true" 允许我们使用正斜杠来匹配反斜杠。这使得正则表达式更简洁。

    接下来,我将通过将其分解为多个部分来解释粗糙的正则表达式。

    我把((?:[^/]+/)*) 炸成...

    (
        (?:
            [^/]+
            /
        )
        *
    )
    

    各部分的含义:

    (  -- capture group 1 starts
        (?:  -- non-capturing group starts
            [^/]+  -- greedily match as many non-directory separators as possible
            /  -- match a single directory-separator character
        )  -- non-capturing group ends
        * -- repeat the non-capturing group zero-or-more times
    )  -- capture group 1 ends
    

    以上部分重复匹配尽可能多的子目录。 () 将所有匹配项放入捕获组 1。稍后,捕获组 1 可用于 &lt;regexpmapper&gt;to 属性和 \1 反向引用。

    如果路径中没有 / 目录分隔符,则上述部分将不匹配任何内容,并且捕获组 1 将为空字符串。

    移动到正则表达式的末尾,$$ 将正则表达式锚定到 &lt;fileset&gt; 选择的每个路径的末尾。

    在双美元符号表达式$$ 中,第一个$ 转义了第二个$。这是必要的,因为 Ant 会将单个 $ 视为属性引用的开始。

    [^/]+ 仅匹配文件名,因为它匹配路径末尾不是目录分隔符 (/) 的所有字符。

    示例

    鉴于以下目录结构...

    - copy (dir)
        - new (dir)
            - notthis.b
            - testthis.a
        - anythis.a
    

    ...Ant 输出...

    [copy] Copying 2 files to C:\ant\paste
    [copy] Copying C:\ant\copy\anythis.a to C:\ant\paste\that.a
    [copy] Copying C:\ant\copy\new\testthis.a to C:\ant\paste\new\that.a
    

    【讨论】:

    • 感谢您的回答。此 regexpmapper 将复制所有文件,无论其名称和扩展名如何。我只想复制名称中包含“this”单词和“.a”扩展名的文件。有什么帮助吗?
    • @HelloWorld 我已经更新了我的答案以使用&lt;fileset&gt;includes 属性只选择以*this* 结尾的*this* 文件。
    • 非常感谢。有效。我注意到的一件事是,如果我将“anythis.a”放在“复制”目录本身中,它不会被粘贴到“粘贴”目录中,因为它可以工作的子目录。
    • @HelloWorld 我已经更新了我的答案,以使用一个相当复杂的正则表达式来匹配根目录中的文件。它将匹配“复制”本身中的.a 文件。
    • 工作就像一个魅力。谢谢。
    【解决方案2】:

    试试这个regexpmapper:

    <regexpmapper from="^(.*)/([^/]*)this(.*)\.a$$" to="\1/that\3"/>
    

    这会切断路径 (\1) 和文件名前缀 (\2),因此您可以保留目录结构。

    此外,如果您在替换字符串中使用\3,则可以保留文件扩展名。

    【讨论】:

    • 我试过你提到的regexpmapper。它正确地复制了目录结构,但没有复制和重命名包含“this”字并具有“.a”扩展名的实际文件。所有文件夹都是空的。
    猜你喜欢
    • 2011-01-07
    • 2010-11-01
    • 2016-10-03
    • 2012-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    相关资源
    最近更新 更多