2009-04-22 118 views
18

我想从.bat文件中获取文件的父目录。所以,给定一个变量设置为"C:\MyDir\MyFile.txt",我想获得"C:\MyDir"。换句话说,在典型的UNIX环境中相当于dirname()功能。这可能吗?如何在批处理文件中获得dirname()的等效项?

+1

我加了一个关于带空格的文件名的注释;忘记与那些测试。 – Joey 2009-04-22 17:40:14

回答

20
for %%F in (%filename%) do set dirname=%%~dpF 

这将设置%dirname%存储在%filename%文件名的驱动器和目录。

虽然,小心使用包含空格的文件名。他们要么必须与周围的引号设置:

set filename="C:\MyDir\MyFile with space.txt" 

或你必须把周围参数报价在for循环:

for %%F in ("%filename%") do set dirname=%%~dpF 

这两种方法都可以工作,无论是在获得同一时间“T :-)

+0

我想你的意思是,“把*引号*放在for循环中的参数周围:” – aphoria 2009-04-22 18:57:37

+0

是的,谢谢。目前无法正确思考:) – Joey 2009-04-22 19:45:52

+0

@mosh,硬链接的预期结果是什么?另请注意,您的解决方法对Unicode文件名和控制台字体很敏感。 – Joey 2016-07-09 10:37:26

6

如果因任何原因,你不能使用(没有命令扩展等),你可能能够与闪避.. \黑客:

set file=c:\dir\file.txt 
set dir=%file%\..\ 
3

for循环的问题在于,它会在字符串的末尾留下尾部\。这会导致问题,如果你想多次获取dirname。也许你需要获取包含该文件的目录的祖父目录的名称,而不仅仅是父目录。第二次使用for循环技术将删除\,并且不会获得祖父目录。

这就是你不能简单地做到以下几点。

set filename=c:\1\2\3\t.txt 
for %%F in ("%filename%") do set dirname=%%~dpF 
for %%F in ("%dirname%") do set dirname=%%~dpF 

这将设置dirname为“c:\ 1 \ 2 \ 3”,而不是“c:\ 1 \ 2”。

以下功能通过删除尾部\来解决该问题。

:dirname file varName 
    setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION 
    SET _dir=%~dp1 
    SET _dir=%_dir:~0,-1% 
    endlocal & set %2=%_dir% 
GOTO :EOF 

它被调用如下。

set filename=c:\1\2\3\t.txt 
call :dirname "%filename%" _dirname 
call :dirname "%_dirname%" _dirname 
相关问题