如何从绝对路径中剥离基本目录以获取相对路径?

25
在我的项目的build.xml文件中,我定义了一个属性:
<property name="somedir.dir" location="my_project/some_dir"/>

${somedir.dir}的值将会是绝对路径:/home/myuser/my_project/some_dir

我需要的只是相对路径./my_project/some_dir,不需要${basedir}的值/home/myuser。使用Ant,我该怎么做呢?

到目前为止,我通过将属性转换为路径,然后使用"pathconvert"找到了一个解决方案,但我认为这不是一个好的解决方案:

<path id="temp.path">
    <pathelement location="${somedir.dir}" />
</path>
<pathconvert property="relative.dir" refid="temp.path">
    <globmapper from="${basedir}/*" to="./*" />
</pathconvert>

还有没有其他更优秀的建议?

5个回答

44

自 Ant 1.8.0 版本起,您可以使用 Ant property 任务relative 属性来完成此操作。

例如:

<property name="somedir.dir" location="my_project/some_dir"/>
<echo message="${somedir.dir}" />

<property name="somedir.rel" value="${somedir.dir}" relative="yes" />
<echo message="${somedir.rel}" />

导致:

 [echo] /home/.../stack_overflow/ant/my_project/some_dir
 [echo] my_project/some_dir

1
请注意,“basedir”属性也非常有用,因为它允许使用另一个目录而不是默认的基本目录。感谢您向我们展示了这个解决方案,它比使用带有一些正则表达式的映射器更容易和可靠。 - gouessej

7

一种更简洁的解决方案是在<pathconvert>标签内指定somepath

<pathconvert property="relative.dir">
  <path location="${somepath}"/>
  <globmapper from="${basedir}/*" to="./*" />
</pathconvert>

3

您可以尝试使用 Ant 的 basename 任务。 如果您已经有:

<property name="somedir" value="/path/to/file/here" />
<basename file="${somedir}" property="somebasedir" />
<echo>${somebasedir}</echo>

被回显的值是“here”。它似乎只提供最终目录,可能不能满足您想要的所有内容。

2
这就是我想要的...四年后。 - mfa

1

这是我在Windows上采用的方法,改编自@Garns的答案:

<path id="uploadFilePath">
    <fileset dir="${wcm.folderName}">
        <include name="*" />
        <exclude name="*.attr" />
    </fileset>
</path>

<pathconvert property="relFilelist">
    <path refid="uploadFilePath" />
    <mapper>
        <globmapper from="${wcm.folderName}/*" to="*" handledirsep="true" />
    </mapper>
</pathconvert>

在IT相关的领域中,我认为handledirsep="true"在globmapper中非常重要。否则,无论我如何调整正斜杠和反斜杠,它都无法正常工作。(在我的ant脚本中,我所有的斜杠都是正斜杠,这样我就可以在类Unix系统上运行它们)。我的Ant版本是1.8.1。


0

location 会自动使用项目的 basedir 展开路径。因此,我认为 value 选项可以让您更好地控制:

<property name="base.dir" value="/home/myuser"/>

并且

<property name="somedir.dir" value="${base.dir}/some_dir"/>

我觉得你误解了我的问题。我已经有一个给定的路径 "${base.dir}/some_dir",我需要获取相对路径 "./some_dir"。 - blackicecube
当你已经有${somedir.dir}时,为什么需要提取some_dir - Anonymous
${somedir.dir} 大概是 "/home/blah/mydirectory" 这样的路径,问题是如何从中获取 "./mydirectory"。因此,你不能只使用 ${somedir.dir}。在 nant 中有很多内置函数,比如 path::get-directory-name,但我似乎找不到 Ant 中是否存在这些函数。我也需要知道如何做到这一点。 - christophercotton
2
是的。但是你可以看到,我正在使用value而不是location。因此,如果您将base.dir设置为/home/blah并将somedir.dir设置为mydirectory,则它们将分开,并且绝对路径将为${base.dir}/${somedir.dir}。为什么要将绝对路径压缩到具有选项位置的base.dir中,然后寻找从中提取工作目录的方法呢? - Anonymous
2
如果变量是由其他任务的输出产生的,那么它是否仍然为“true”? - dm76

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接