我想使用Ant重命名文件,以维护它们的目录结构。
例如,假设以下目录结构:
- copy
- new
- testthis.a
使用下面的代码,我可以使用复制任务将包含"this"单词的文件重命名为"that.a",但它们都被粘贴到"粘贴"目录中,失去了目录结构。
<copy todir="paste" overwrite="true">
<fileset dir="copy"/>
<regexpmapper from="^(.*)this(.*).a$$" to="that.a"/>
</copy>
输出:
- paste
- that.a
如果我将regexmapper更改为(注意\a之前的1(:
<regexpmapper from="^(.*)this(.*).a$$" to="1that.a"/>
它生成了正确的目录结构,但总是在单词"this"之前加上"that">
输出:
- paste
- new
- testthat.a
有没有任何方法可以重命名文件,保持其目录结构,而不需要预先挂起或附加任何单词?
有没有其他映射器可以用于相同的映射?
如有任何帮助,我们将不胜感激。
<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
上述部分重复匹配尽可能多的子目录。CCD_ 3和CCD_。稍后,可以在具有1
反向引用的<regexpmapper>
的to
属性中使用捕获组1。
如果路径中没有/
目录分隔符,那么上面的部分将不匹配,捕获组1将是一个空字符串。
移动到正则表达式的末尾,$$
将正则表达式锚定在<fileset>
选择的每个路径的末尾。
在双美元符号表达式$$
中,第一个$
逃脱第二个$
。这是必要的,因为Ant会将单个$
视为属性引用的开始。
[^/]+
只匹配文件名,因为它匹配路径末尾不是目录分隔符的所有字符(/
(。
示例
给定以下目录结构。。。
- copy (dir)
- new (dir)
- notthis.b
- testthis.a
- anythis.a
Ant输出。。。
[copy] Copying 2 files to C:antpaste
[copy] Copying C:antcopyanythis.a to C:antpastethat.a
[copy] Copying C:antcopynewtestthis.a to C:antpastenewthat.a
尝试此regexpmapper
:
<regexpmapper from="^(.*)/([^/]*)this(.*).a$$" to="1/that3"/>
这会剪切路径(1
(和文件名前缀(2
(,因此可以保留目录结构。
此外,如果在替换字符串中使用3
,则可以保留文件扩展名。