Windows 拆分路径并获取批处理脚本中的最后一个文件夹名称

Windows 拆分路径并获取批处理脚本中的最后一个文件夹名称,windows,for-loop,batch-file,cmd,directory,Windows,For Loop,Batch File,Cmd,Directory,我想用\拆分字符串(有路径),并在变量中取最后一个文件夹名。请帮忙 e、 g mypath=D:\FOLDER1\FOLDER2\FOLDER3\ 我想要FOLDER3在一个变量中 我尝试使用下面的命令,如果最后一个字符不是\,则该命令有效: for %f in (C:\FOLDER1\FOLDER2\FOLDER3) do set myfolder=%~nxf 如果最后一个字符是\ 此外,如果使用如下变量,则它不起作用: 对于(%mypath%)中的%f,请设置myfolder=%~nxf

我想用
\
拆分字符串(有路径),并在变量中取最后一个文件夹名。请帮忙

e、 g
mypath=D:\FOLDER1\FOLDER2\FOLDER3\

我想要FOLDER3在一个变量中

我尝试使用下面的命令,如果最后一个字符不是
\
,则该命令有效:

for %f in (C:\FOLDER1\FOLDER2\FOLDER3) do set myfolder=%~nxf
如果最后一个字符是
\

此外,如果使用如下变量,则它不起作用: 对于(%mypath%)中的%f,请设置myfolder=%~nxf

@echo off

set MYDIR=C:\FOLDER1\FOLDER2\FOLDER3\
set MYDIR1=%MYDIR:~0,-1%

for %%f in (%MYDIR1%) do set myfolder=%%~nxf
echo %myfolder%
输出

FOLDER3
尝试:

工程还包括:

for %f in (C:\FOLDER1\FOLDER2\FOLDER3.) do set myfolder=%~nxf

当当前文件夹包含空间时,请尝试以下操作:

@echo off
for %%f in ("%CD%") do set LastPartOfFolder=%%~nxf

echo %LastPartOfFolder%

下面的脚本包含一个子例程,该例程将处理带有或不带有尾部斜杠的路径,以及相同的示例测试

@echo off

::-----------------------------------------------------------------------------
:: Main script - testing the :get_last_folder subroutine.
::-----------------------------------------------------------------------------
setlocal enableExtensions

:: no trailing slash
call :get_last_folder C:\path\to\folder_0 _result
echo result: %_result%

:: one trailing slash
call :get_last_folder C:\path\to\folder_1\ _result
echo result: %_result%

:: extra slashes -- Windows doesn't care.
call :get_last_folder C:\path\to\folder_2\\ _you_can_use_any_variable_name
echo result: %_you_can_use_any_variable_name%

:: spaces in path
call :get_last_folder "C:\path\to\folder with spaces" _result
echo result: %_result%

:: no return variable -- Subroutine will ECHO the value.
call :get_last_folder C:\path\to\folder_to_echo

:: path of current directory
call :get_last_folder "%cd%" _result
echo result: %_result%

:: path of current directory after changing it
pushd "%userprofile%"
call :get_last_folder "%cd%" _result
echo result: %_result%

:: location of this file, independent of current directory
call :get_last_folder "%~dp0" _result
echo result: %_result%

:: restore previous current directory, cuz I'm not rude.
popd 

exit /b 

::-----------------------------------------------------------------------------
:: Subroutine
::-----------------------------------------------------------------------------
:get_last_folder <path> [return]
:: Extracts the last folder in a file system directory path.
:: Path may include zero, one, or more trailing slashes, but not a file name.

REM Use SETLOCAL to keep our subroutine variables from affecting the parent.
REM It also allows us to limit delayed variable expansion to where it's needed.
setlocal enableDelayedExpansion

REM Add a trailing slash to ensure the last element is seen as a folder.
REM If it already had a trailing slash, that's okay: extras are ignored.
set "_full_path=%~1\"

REM The caller can provide a variable name that we'll set to the return value.
REM If no return variable is given, we'll just ECHO the value before exiting.
set "_return=%~2"

for /f "delims=" %%F in ("%_full_path%") do (
    REM Treat the path as a string to avoid "file not found" error.
    REM Use loop variable expansion to get the "path" part of the path.
    REM The resulting string will always have exactly one trailing slash.
    set "_path=%%~pF"

    REM Use substring substitution to remove the trailing slash.
    REM Delayed expansion lets us access the new value while inside the loop.
    set "_path=!_path:~0,-1!"

    REM Without a trailing slash, the last element is now seen as a file.
    REM Use the "name" substring to get the value we came for.
    for /f "delims=" %%D in ("!_path!") do (
        set "_name=%%~nD"
    )
)

REM 
if defined _return (
    set "_command=set %_return%=%_name%"
) else (
    set "_command=echo\%_name%"
)

REM The "ENDLOCAL &" trick allows setting variables in the parent environment.
REM See https://ss64.com/nt/syntax-functions.html for more details.
endlocal & %_command%

goto :eof
@echo关闭
::-----------------------------------------------------------------------------
::主脚本-测试:get_last_文件夹子例程。
::-----------------------------------------------------------------------------
setLocalEnableExtensions
::没有尾随斜杠
调用:获取\u last\u文件夹C:\path\to\folder\u 0\u结果
回显结果:%\u结果%
::一个尾随斜杠
调用:获取\u last\u文件夹C:\path\to\folder\u 1\\u结果
回显结果:%\u结果%
::额外的斜杠--Windows不在乎。
调用:获取\u last\u文件夹C:\path\to\folder\u 2\\\您可以\u使用任何\u变量\u名称
回显结果:%\u您\u可以\u使用任何变量\u名称%
::路径中的空格
调用:获取\u最后\u文件夹“C:\path\to\folder with spaces”\u结果
回显结果:%\u结果%
::无返回变量--子例程将回显该值。
调用:获取\u last\u文件夹C:\path\to\folder\u to\u echo
::当前目录的路径
调用:获取\u最后\u文件夹“%cd%”\u结果
回显结果:%\u结果%
::更改当前目录后的路径
pushd“%userprofile%”
调用:获取\u最后\u文件夹“%cd%”\u结果
回显结果:%\u结果%
::此文件的位置,独立于当前目录
调用:获取\u最后一个\u文件夹“%~dp0”\u结果
回显结果:%\u结果%
::还原以前的当前目录,因为我不是粗鲁的。
流行音乐
退出/b
::-----------------------------------------------------------------------------
::子程序
::-----------------------------------------------------------------------------
:获取最后一个文件夹[返回]
::提取文件系统目录路径中的最后一个文件夹。
::路径可以包含零、一个或多个尾随斜杠,但不能包含文件名。
REM使用SETLOCAL来防止子程序变量影响父变量。
REM它还允许我们将延迟变量扩展限制在需要的地方。
setlocal enableDelayedExpansion
REM添加尾部斜杠以确保最后一个元素被视为文件夹。
REM如果它已经有一个尾随斜杠,那没关系:多余的被忽略。
设置“\u完整路径=%~1\”
REM调用方可以提供一个变量名,我们将其设置为返回值。
REM如果没有返回变量,我们将在退出之前回显该值。
设置“_return=%~2”
对于/f“delims=“%%f in”(“%\u full\u path%”)do(
REM将路径视为字符串以避免“未找到文件”错误。
REM使用循环变量展开来获取路径的“路径”部分。
REM生成的字符串始终只有一个尾随斜杠。
设置“_path=%%~pF”
REM使用子字符串替换删除尾部斜杠。
REM延迟扩展允许我们在循环内部访问新值。
设置“\u路径=!\u路径:~0,-1!”
REM没有尾部斜杠,最后一个元素现在被视为文件。
REM使用“name”子字符串获取我们想要的值。
对于/f“delims=“%%D in(!\u path!”)执行以下操作(
设置“\u name=%%~nD”
)
)
雷姆
如果已定义,则返回(
设置“\u命令=设置%\u返回%=%\u名称%”
)否则(
设置“\u命令=echo\%\u名称%”
)
REM“ENDLOCAL&”技巧允许在父环境中设置变量。
REM Seehttps://ss64.com/nt/syntax-functions.html 更多细节。
endlocal&%\u命令%
后藤:eof
我知道它看起来很长,但这只是因为测试用例和大量的注释;主子程序代码大约有10行,如果你把它放在它自己的文件中,其中的一些代码可能会消失

批处理脚本子例程不是真正的函数,因为它由解释器或编译器求值,然后返回一个适当的值。相反,它们是一种经过修改的、奇特的GOTO形式,支持局部变量。尽管如此,它们在将代码分解为可重用部分和传递值方面仍然很有用。虽然“伪函数”可能是一个更好的术语,但人们通常只是说“函数”,所以搜索“批脚本函数”会得到有用的结果

这是关于批处理“函数”如何工作的最古老和最好的文章之一:

这是对函数的更简单、更简短的解释,并在脚本中引用:

要了解CMD中循环的内部情况,请参阅优秀的Rob van der Woude撰写的以下文章:

有时候读书是不够的。这里有一组很好的练习,可以真正掌握一些东西:
(自从我上次查看该页面以来,该页面上的CSS变得非常混乱,但您可以将文本复制到文件中,这样就可以了。)

这对我很有用,不管路径是否有空格、特殊字符(&或类似字符)或结尾处是否有\都可以


要将其放入一个简单的子例程中,以正确处理空格:

@Echo Off

Rem Get name of folder containing this script.
Call :ParentFolderNamGet "%~dp0"

Rem Debug the variable.
Echo ParFldNam is [%ParFldNam%]

Pause

Rem Done with this script.
GoTo :EOF

Rem Argument to this subroutine must be a validly-formatted path (ends with a trailing backslash).
:ParentFolderNamGet

Rem Drop any enclosing double-quotes from caller's path, ensuring the last character is the path's trailing backslash.
Set Prm=%~1

Rem Drop trailing backslash; this converts the string from %~dp1 to %~dpn1 (the last folder name becomes a file name).
Set Prm=%Prm:~0,-1%

Rem Get only the 'filename' portion from the validly-formatted pathname.
For %%A In ("%Prm%") Do Set ParFldNam=%%~nxA

Rem Result is in %ParFldNam%
GoTo :EOF

写得不错的家伙。虽然我喜欢简单

rem set with or without spaces or trailing slash, but quotes are important...
set "_foldername=..."

rem cd command doesn't care if there's a trailing slash or not, and don't forget quotes...
cd "%_foldername%"   rem or pushd/popd if desired

rem as per @Dirk, use the %cd% system variable instead of the manually set variable,
rem this will return the current directory, always w/o a trailing slash.
rem again, as per @Dirk, quotes cause it to do spaces correctly.
for %%f in ("%cd%") do set _lastfolder=%%~nf

rem popd here, if used.

echo %_lastfolder%
很简单,对吧


所以。。。为什么每个人都使用
%nxf%
(文件名)而不是
%nf%
(文件夹)?

%MYDIR:~0,-1%
似乎是某种子字符串方法,但有人能解释for循环中发生了什么吗?myfolder中缺少最后一个字符!所以它实际上不起作用。输入文件夹:…\blalal\Control Freak返回:Control FreaIt看起来是因为末尾没有斜杠。如果附加一个,上述操作将起作用。或者,您可以删除实际上删除最后一个字符的行
set MYDIR1=%MYDIR1:~0,-1%
。为了安全起见,你可以检查一下
@Echo Off

Rem Get name of folder containing this script.
Call :ParentFolderNamGet "%~dp0"

Rem Debug the variable.
Echo ParFldNam is [%ParFldNam%]

Pause

Rem Done with this script.
GoTo :EOF

Rem Argument to this subroutine must be a validly-formatted path (ends with a trailing backslash).
:ParentFolderNamGet

Rem Drop any enclosing double-quotes from caller's path, ensuring the last character is the path's trailing backslash.
Set Prm=%~1

Rem Drop trailing backslash; this converts the string from %~dp1 to %~dpn1 (the last folder name becomes a file name).
Set Prm=%Prm:~0,-1%

Rem Get only the 'filename' portion from the validly-formatted pathname.
For %%A In ("%Prm%") Do Set ParFldNam=%%~nxA

Rem Result is in %ParFldNam%
GoTo :EOF
rem set with or without spaces or trailing slash, but quotes are important...
set "_foldername=..."

rem cd command doesn't care if there's a trailing slash or not, and don't forget quotes...
cd "%_foldername%"   rem or pushd/popd if desired

rem as per @Dirk, use the %cd% system variable instead of the manually set variable,
rem this will return the current directory, always w/o a trailing slash.
rem again, as per @Dirk, quotes cause it to do spaces correctly.
for %%f in ("%cd%") do set _lastfolder=%%~nf

rem popd here, if used.

echo %_lastfolder%