使用DOS批处理脚本获取特定文件的父目录名称

时间:2010-03-07 11:04:29

标签: windows batch-file scripting cmd

我需要在DOS中找到文件的父目录的名称

代表

假设这是目录

C:\test\pack\a.txt

我有一个脚本,询问我文件名

C:\\>getname.bat     
enter file name: c:\test\pack\a.txt   

现在脚本应该只返回文件的父名称。

pack           

而不是文件的整个父路径。

c:\test\pack   

9 个答案:

答案 0 :(得分:12)

如果父目录名称包含空格,则上面的第一个答案不起作用。以下作品:

@echo off
setlocal

set ParentDir=%~p1
set ParentDir=%ParentDir: =:%
set ParentDir=%ParentDir:\= %
call :getparentdir %ParentDir%
set ParentDir=%ParentDir::= %

echo ParentDir is %ParentDir%
goto :EOF

:getparentdir
if "%~1" EQU "" goto :EOF
Set ParentDir=%~1
shift
goto :getparentdir

使用参数“C:\ Temp \ Parent Dir With Space \ myfile.txt”调用上面的代码如下:

>GetParentDir "C:\Temp\Parent Dir With Space\myfile.txt"
ParentDir is Parent Dir With Space

上面的工作方法是用冒号替换空格(这些在Windows路径中不应该存在),然后用空格替换目录分隔符,以便将各个目录作为单独的参数传递给getparentdir。函数getparentdir循环,直到找到它的最后一个参数。最后,结果中的任何冒号都被空格替换。

答案 1 :(得分:11)

请参阅this问题

@echo OFF
set mydir="%~p1"
SET mydir=%mydir:\=;%

for /F "tokens=* delims=;" %%i IN (%mydir%) DO call :LAST_FOLDER %%i
goto :EOF

:LAST_FOLDER
if "%1"=="" (
    @echo %LAST%
    goto :EOF
)

set LAST=%1
SHIFT

goto :LAST_FOLDER

答案 2 :(得分:8)

获取批处理文件的父文件夹非常简单:

@echo off
for %%a in ("%~dp0\.") do set "parent=%%~nxa"
echo %parent%

对于文件路径的父级,根据问题:

@echo off
for %%a in ("c:\test\pack\a.txt") do for %%b in ("%%~dpa\.") do set "parent=%%~nxb"
echo %parent%

答案 3 :(得分:1)

您可以使用vbscript,例如将以下内容保存为getpath.vbs

Set objFS = CreateObject("Scripting.FileSystemObject")
Set objArgs = WScript.Arguments
strFile = objArgs(0)
WScript.Echo objFS.GetParentFolderName(strFile)

然后在命令行或批处理中执行此操作

C:\test>cscript //nologo getpath.vbs c:\test\pack\a.txt
c:\test\pack

如果您想要批处理方法,可以查看for /?

  %~fI        - expands %I to a fully qualified path name
  %~dI        - expands %I to a drive letter only
  %~pI        - expands %I to a path only

答案 4 :(得分:1)

这是一种不使用CALL的方式,我相信速度更快。Based on jeb's splitting function(如果目录名称包含!,则可能会失败):

@echo off

set "mydir=%~p1"
SET mydir=%mydir:~0,-1%

setlocal EnableDelayedExpansion
set LF=^


rem ** Two empty lines are required

for %%L in ("!LF!") DO (
    set "dir_name=!mydir:\=%%L!"
)
for /f "delims=" %%P in (""!dir_name!"") do set "dn=%%~P"
echo %dn%

exit /b 0 

答案 5 :(得分:1)

在查找我的脚本的父目录时,我发现djangofan和paranoid的答案的这种方法组合既简单又完全正确:

set FULL_PATH=%~dp0
set FULL_PATH=%FULL_PATH:~1,-1%
for %%i in ("%FULL_PATH%") do set "PARENT_FOLDER=%%~ni"
echo %PARENT_FOLDER%

由于你想要处理用户输入,你必须做一些最小的额外工作,以处理合法的变化,如C:\ foo \ bar \ a.txt与C:\ foo \ bar \ a.txt或C:/foo/bar/a.txt。这可能对您有用:

@setlocal
@echo off

call:GET_PARENT_FOLDER C:\foo\bar\a.txt
echo %PARENT_FOLDER%
call:GET_PARENT_FOLDER C:\foo\bar\\a.txt
echo %PARENT_FOLDER%
call:GET_PARENT_FOLDER c:/foo/bar/a.txt
echo %PARENT_FOLDER%

pause
goto:EOF

:GET_PARENT_FOLDER
:: Strip the filename, so we get something like this: 'C:\foor\bar\'
set "_FULL_PATH=%~dp1"

:: Strips all dangling '\' and '/' in a loop, so the last folder name becomes accessible
:_STRIP
if not "%_FULL_PATH:~-1%"=="\" if not "%_FULL_PATH:~-1%"=="/" goto:_STRIP_END
set "_FULL_PATH=%_FULL_PATH:~1,-1%"
goto:_STRIP
:_STRIP_END

:: We need the context of a for-loop for the special path operators to be available
for %%i in ("%_FULL_PATH%") do set "PARENT_FOLDER=%%~ni"

goto:EOF

答案 6 :(得分:1)

DaDummy的想法在更实用的可重用功能中得以实现。现在还包括_full_path的第一个字符。

set map=D:\test1\test2\test3\test4.txt
call:get_parent_path "%map%"
echo full_path is %_full_path%
call:get_parent_path %_full_path%
echo full_path is %_full_path%
call:get_last_path %_full_path%
echo last_path is %_last_path%
goto :eof

:get_parent_path
set "_full_path=%~dp1"
:_strip
if not "%_full_path:~-1%"=="\" if not "%_full_path:~-1%"=="/" goto:_strip_end
set "_full_path=%_full_path:~0,-1%"
goto:_strip
:_strip_end
exit /b

:get_last_path
set "_last_path=%~nx1"
exit /b

::result:
::full_path is D:\test1\test2\test3
::full_path is D:\test1\test2
::last_path is test2

答案 7 :(得分:0)

这是另一种解决方案:

SET LAST=%CD%
SET PARENTNAME=NONE
cd /D C:\test\pack
FOR %%I in (%CD%) do SET PARENTNAME=%%~nI
cd /D %LAST%
ECHO %PARENTNAME%

%% ~nI:' ~n'从存储在%% I变量中的路径中提取名称 cd:' / D'添加到磁盘之间的参数也是

答案 8 :(得分:0)

call :set_dirname "%cd%"
echo %DIRNAME%


:set_dirname
set DIRNAME=%~n1
goto :eof