在MSBuild中,GetDirectoryNameOfFileAbove
函数找到包含某个文件的第一个祖先目录。
对于那些不熟悉MSBuild功能的人,这是一个例子。
我有一个文件:
c:\projects\root.txt
我希望能够运行如下脚本:
c:\projects\everything\foo\bar\myscript.cmd
并希望找到c:\projects\
,因为它是c:\projects\everything\foo\bar\
中最接近该祖先文件的祖先。该脚本还应该能够检测文件何时不存在于任何祖先中,并且只能得到一个空字符串。
如何在(Windows)批处理脚本中实现相同的目标?
答案 0 :(得分:0)
@echo off
setlocal EnableDelayedExpansion
set "theFile=%~1"
rem Get the path of this Batch file, i.e. "c:\projects\everything\foo\bar\"
set "myPath=%~DP0"
rem Process it as a series of ancestor directories
rem i.e. "c:\" "c:\projects\" "c:\projects\everything\" etc...
rem and search the file in each ancestor, taking as result the last one
set "result="
set "thisParent="
set "myPath=%myPath:~0,-1%"
for %%a in ("%myPath:\=" "%") do (
set "thisParent=!thisParent!%%~a\"
if exist "!thisParent!%theFile%" set "result=!thisParent!"
)
if defined result (
echo %result%
) else (
echo There is not such file in my ancestors
)
将文件名作为此批处理文件的参数。例如,如果您将此文件命名为GetDirectoryNameOfFileAbove.bat
,则可以这样使用它:
GetDirectoryNameOfFileAbove root.txt
答案 1 :(得分:0)
我可以用2(长行)命名。代码很短。解释很长。
@rem will search up to 8 levels up from here
@Set Ancestry=.;..;..\..;..\..\..;..\..\..\..;..\..\..\..\..;..\..\..\..\..\..;..\..\..\..\..\..\..;..\..\..\..\..\..\..;..\..\..\..\..\..\..\..;..\..\..\..\..\..\..\..\..;
@REM %~dp$Ancestry:1 -- search paths in Ancestry for arg 1
@REM finds files of any type, not just exe
@REM LocalTop is either the folder where arg 1 (%1) was found or empty
@Set LocalTop=%~dp$Ancestry:1
工作原理:
来自FOR /?:
%~$PATH:I - searches the directories listed in the PATH
environment variable and expands %I to the
fully qualified name of the first one found
If the environment variable name is not
defined or the file is not found by the
search, then this modifier expands to the
empty string
对我来说不明显的是,它不仅限于环境变量'PATH'。您可以提供任何变量,这是Ancestry所在的变量。