例如,假设这是目录。
C:\test\pack\a.txt
我有一个脚本,它会要求我输入文件名。
C:\\>getname.bat
enter file name: c:\test\pack\a.txt
现在脚本应该只返回文件的父级名称。
pack
并且不是整个父级路径到文件。c:\test\pack
C:\test\pack\a.txt
我有一个脚本,它会要求我输入文件名。
C:\\>getname.bat
enter file name: c:\test\pack\a.txt
现在脚本应该只返回文件的父级名称。
pack
并且不是整个父级路径到文件。c:\test\pack
获取批处理文件的父文件夹可能非常简单:
@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%
如果父目录名称包含空格,则上面的第一个答案无效。以下内容有效:
@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函数会循环直到找到最后一个参数。最后,结果中的任何冒号都被替换为空格。
请参考这个问题。
@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
你可以使用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
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
CALL
的方式,我认为它更快。基于jeb的分割函数(如果目录名包含!
可能会失败):@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
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
这里有另一种解决方案:
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' 参数也可用于在磁盘之间切换
call :set_dirname "%cd%"
echo %DIRNAME%
:set_dirname
set DIRNAME=%~n1
goto :eof
以下是一种检索通过CMD命令访问的文件所在文件夹名称的方法。使用OP的示例,文件路径为C:\test\pack\a.txt
,您希望您的命令提取出最后一个文件夹名称"pack"。(正如dgnuff在评论中指出的那样,目前得分最高的答案是针对不同问题的答案,如果您处于OP的情况下,它将无法帮助您。)
我使用嵌套的FOR循环来实现它。以下是一个示例,命令将出现在批处理文件中,而不是直接输入到命令行中:
FOR %%Z in ("*.txt") do (FOR %%I in ("%%~dpZ.") do (copy "%%~Z" "%%~dpZ%%~nxI.archive\%%~nxZ" ))
这个示例批处理命令将文本文件复制到以文件夹名称命名的子文件夹中:
C:\test\pack\a.txt -> C:\test\pack\pack.archive\a.txt
C:\test\pick\b.txt -> C:\test\pick\pick.archive\b.txt
E:\A\B\C\D\foo.txt -> E:\A\B\C\D\D.archive\foo.txt
外部 FOR 循环用于复制文件。但是你需要内部 FOR 循环来建立目标路径,因为目标子文件夹的名称基于源文件夹的名称。序列 "%%~dpZ."
— Z 后面跟着那个点 — 检索包含当前文件的文件夹的名称,然后可以通过参数 I
引用它(而 Z
是对正在被复制的文件的引用)。参见 this page 中的“参数扩展”部分以查看用于构建路径的内置变量的详细信息,例如 "%%~dpZ%%~nxI.archive\%%~nxZ"
%~dp0\.
后面添加\..
即可返回一个更高层级的文件夹。例如:for %%a in ("%~dp0\.\..\..\..") do set "parent=%%~nxa"
。 - Matt("%~p1\.")
而不是("%~dp0\.")
。 - VenryxC:\A\B\C.Bat
运行批处理文件,该文件正在处理文件C:\D\E\Foo.txt
- 我不关心批处理文件本身的路径,我关心从文本文件的路径中获取E
。 - dgnuff