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

时间:2013-06-24 15:21:47

标签: 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

如果最后一个字符为\

,则无效

如果使用变量,它也无效: for%f in(%mypath%)设置myfolder =%~nxf

7 个答案:

答案 0 :(得分:26)

@echo off

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

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

输出

FOLDER3

答案 1 :(得分:15)

尝试:

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

也有效:

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

答案 2 :(得分:3)

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

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

echo %LastPartOfFolder%

答案 3 :(得分:0)

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

@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

我知道它看起来很长,但这仅仅是由于测试用例和大量注释;主要子例程代码大约有10行,如果将其放在自己的文件中,其中的一些代码可能会消失。

从解释器或编译器进行评估然后返回一个适当值的意义上说,批处理脚本子例程不是真正的函数。相反,它们是GOTO的一种修饰形式,支持局部变量。尽管如此,它们对于将代码分解为可重用的部分并传递值仍然很有用。虽然“伪函数”可能是一个更好的术语,但人们总是反而会说“函数”,因此搜索“批处理脚本函数”将为您提供有用的结果。

这是最古老和最好的文章之一,批处理“功能”如何工作: https://www.dostips.com/DtTutoFunctions.php

这是一个更简单,简短的功能说明,并在脚本内引用:https://ss64.com/nt/syntax-functions.html

有关CMD的FOR循环中到底发生了什么的解释,请参见出色的Rob van der Woude的这篇文章:https://www.robvanderwoude.com/for.php

有时阅读还不够。这里有一系列练习可以使您真正掌握事物:https://resources.infosecinstitute.com/cmd-exe-loops-part-iii/ (自从我上次查看以来,此页面上的CSS变得一团糟,但是您可以将文本复制到文件中,就可以了。)

答案 4 :(得分:0)

这对我有用,无论路径是否有空格、特殊字符(& 或类似字符)或 \ 结尾(或没有)。

setlocal ENABLEDELAYEDEXPANSION

set "par=%~1"
:loop
for /f "delims=\ tokens=1,*" %%A in ("%par%") do (
    set "_last=%%A"
    set "par=%%B"
)
if NOT "%par%"=="" goto loop
echo Folder last name is :!_last!:

答案 5 :(得分:0)

把它放在一个正确处理空格的简单子程序中:

@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

答案 6 :(得分:0)

写得很棒的家伙。虽然我喜欢简单...

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%(文件夹)?