Batch file 如何从cmd批处理文件中的变量获取目录路径

Batch file 如何从cmd批处理文件中的变量获取目录路径,batch-file,cmd,filepath,Batch File,Cmd,Filepath,在批处理文件中,我有一个包含文件路径的变量: SET VAR1=C:\Folder1\Folder2\File.txt 我想提取目录结构并检索: C:\Folder1\Folder2\ 我读过一些线程,比如我需要使用%~dp0,我认为0是作为参数传递的。我尝试了%~dpVAR1,但没有成功。如何获得我正在寻找的输出,但使用包含文件路径的变量 此外,为了使事情变得困难,我必须在IF条件下执行所有这些操作,这意味着一旦声明变量,我将需要使用引用它而不是%(我在脚本的开头声明了setlocal e

在批处理文件中,我有一个包含文件路径的变量:

SET VAR1=C:\Folder1\Folder2\File.txt
我想提取目录结构并检索:

C:\Folder1\Folder2\
我读过一些线程,比如我需要使用
%~dp0
,我认为
0
是作为参数传递的。我尝试了
%~dpVAR1
,但没有成功。如何获得我正在寻找的输出,但使用包含文件路径的变量

此外,为了使事情变得困难,我必须在
IF
条件下执行所有这些操作,这意味着一旦声明变量,我将需要使用
引用它
而不是
%
(我在脚本的开头声明了
setlocal enableextensions enabledelayedexpansion以允许此操作)

非常感谢您的帮助

谢谢

Andrew

我相信(再次)许多问题都是关于同一主题的(字符串约束或拆分字符串)

我将给你一个模板,并解释为什么
%~dpVAR不起作用

首先,为什么
%~dpVAR无效

在讨论修饰符之前,让我们先讨论一下参数。您可能知道批处理文件可以相互解析参数。这些参数可以通过在数字0-9前面使用一个百分号(%)来调用。据我所知(可能有人已经为更多的参数做了分析),只能分析9个参数。您可能认为这是错误的(有10个参数是正确的?)。参数1-9被解析为批处理文件(或其中的函数),%0是批处理文件(或函数名)的文件路径。如果您仔细看,
%~dp0
与%0有一些相似之处(实际上并非如此)。这将在下文讨论

其次,术语
%~dp0
中有修饰符。修饰符是用来修改变量(只有在参数和在
中为
循环声明的参数的情况下,您知道那些带有双百分号的变量,如%%i)和参数。修饰符
d
仅将参数扩展为驱动器号,而
p
仅将参数扩展为路径。您可能会认为这些会自相矛盾,但可以将参数组合起来创建极其古怪的格式

因此,正如您所看到的,尝试用变量名替换0失败,因为没有为这类事情指定它

现在,转到模板

您可以这样约束变量(并将其放入其他变量中):
set变量=!变量:~偏移量,数量

如果这看起来让人困惑,请不要担心,我将解释组件

首先,请注意没有
/a
开关。这是因为这不是一个数学函数(我真的不知道为什么我添加了这个)。因此,在我解释之前,这里有一个示例,说明它将如何处理值为
0123456789
的变量名
numbers

set numbers=!numbers:~5,1!
通过使用这行代码,
数字
现在等于
5
。这是因为它正在用原始值的较小版本重新创建变量(这很难解释)。如您所见,上面的模板上有一个
5
,其中
offset
。这是因为它跳过了前5个字符,并将变量设置为下一个
amount
,或
1
字符(我真的希望您得到这个)

因此,基本上,它将变量设置为不同(或相同)变量的较短值,该值由偏移量和其中包含的字符数决定

我真的希望这能有所帮助,因为我可能一个字都听不懂


有人能将这个可怜的家伙重定向到一个更好地解释这一点的链接吗(我试过了,好吧!)?

您试图在环境变量上使用参数扩展语法-这是行不通的。但做你想做的事情相对容易

使用呼叫(相对较慢):

使用FOR,假设变量不包含任何通配符(fast)

如果变量可能包含通配符,则使用FOR(也是fast)

注1:如果变量不包含完整路径,则所有解决方案将尝试将名称解析为绝对路径,并返回完整绝对路径。例如,如果var包含
foobar\test.txt
,则解决方案将包括当前目录的完整路径,即使找不到该文件。类似于
c:\pathToCurrentDirectory\foobar\

注2:上述所有解决方案将从路径中删除所有引号

注3:路径可能包括
字符,这将在扩展
%~dp1
%~dpF
时导致问题,因为您已启用延迟扩展。延迟的扩展将损坏
^
如果值包含
。有一种解决方案涉及到保护两个
^
。下面是应用于上面最后一个解决方案的演示。保护需要正常扩展,并且由于您位于代码块内,因此至少需要一次调用。它可以在没有子例程的情况下完成,但使用子例程更容易。子例程假定变量名为
var

(...
  call :getPath
 ...
)
exit /b

:getPath
set "var=!var:"=!"
set "var=!var:^=^^^^!"
set "var=%var:!=^^^!%" !
for /f "delims=" %%F in ("!var!") do set "var=%%~dpF" !
exit /b
这是否有效:

SET VAR1=C:\Folder1\Folder2\File.txt
echo %var1%
其中Echo是exe的名称


%CD%也可以工作:Echo%CD%

从变量中提取路径的完整示例:

@echo off
set /p Fullpath="Specify full path: "
call :getPath %Fullpath% filename folder
echo %filename%
echo %folder%
pause
exit /b

:getPath
set "%2=%~nx1"
set "%3=%~dp1"
exit /b

你对OP代码不起作用的解释很好,尽管有点罗嗦。处理子字符串操作的其余部分与手头的问题无关。你知道为什么你的第二个示例在删除引号和感叹号后才对我有效吗?@fordareh-???问题是明确地试图从变量的内容中提取路径信息。没有感叹号它就不能工作。你一定在做些什么
(...
  call :getPath
 ...
)
exit /b

:getPath
set "var=!var:"=!"
set "var=!var:^=^^^^!"
set "var=%var:!=^^^!%" !
for /f "delims=" %%F in ("!var!") do set "var=%%~dpF" !
exit /b
SET VAR1=C:\Folder1\Folder2\File.txt
echo %var1%
@echo off
set /p Fullpath="Specify full path: "
call :getPath %Fullpath% filename folder
echo %filename%
echo %folder%
pause
exit /b

:getPath
set "%2=%~nx1"
set "%3=%~dp1"
exit /b