Windows批处理 – 循环播放文件夹string并parsing出最后一个文件夹名称

我需要抓取当前正在执行的batch file的文件夹名称。 我一直试图循环使用以下语法(目前是错误的)当前目录:

set mydir = %~p0 for /F "delims=\" %i IN (%mydir%) DO @echo %i 

几个问题,我似乎无法通过'mydir'variables值作为searchstring。 如果我传递命令,它似乎只能工作; 我有语法错误,不能解决原因。

我的想法是用“\”分隔符来遍历文件夹string,但这也会导致问题。 如果我在每个循环上设置一个variables,那么最后一个值将是当前文件夹名称。 例如,给定以下path:

C:\ Folder1中\文件夹2 \ Folder3 \ Archive.bat

我希望parsing出“Folder3”的值。

我需要parsing这个值,因为它的名字是我将在batch file中创build的另一个文件夹的一部分。

非常感谢任何人都可以帮忙。 我可能会彻底地把错误的树叫出来,所以任何其他的方法都会被大大接受。

Solutions Collecting From Web of "Windows批处理 – 循环播放文件夹string并parsing出最后一个文件夹名称"

你是非常接近它:)这应该工作:

 @echo OFF set mydir="%~p0" 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 

由于某些原因,for命令不像'\'作为分隔符,所以我将所有'\'转换为';' 第一个( SET mydir=%mydir:\=;%

经过这些建议的努力,我发现一个成功的使用了以下的1班轮(在Windows 2008中)

 for %%a in (!FullPath!) do set LastFolder=%%~nxa 

当我正在查找当前目录的最后一段时,我发现了这个旧线程。 以前的作者答案引导我以下几点:

 FOR /D %%I IN ("%CD%") DO SET _LAST_SEGMENT_=%%~nxI ECHO Last segment = "%_LAST_SEGMENT_%" 

如前所述,不要忘记用%_LAST_SEGMENT_%创建任何路径的引号(就像我在例子中用%CD%所做的那样)。

希望这可以帮助别人…

这个问题有点老了,但是我不止一次地寻找解决方案,所以我刚才把这个问题放到了一个全新的位置上。

诀窍是我们采取所需的路径,备份一级创建替代文件夹掩码,然后替换文件夹掩码没有任何东西。

要测试它,只需简单地复制并粘贴到任何目录中的命令脚本(.cmd)中,然后运行它。 它只会吐出你目前最深的目录。

笔记:

  • 用你喜欢的任何路径替换%〜dp0(因为它会返回批处理文件运行的最深文件夹,这与%cd%不一样)。
  • 当指定“pathtofind”变量时,确保没有引号,例如c:\ some path,而不是“c:\ some path”。
  • 文件夹掩盖的最初想法是我的
  • 路径中的空间是没有问题的
  • 文件夹深度不是问题
  • 这是由批处理脚本技巧天才http://www.dostips.com/DtCodeBatchFiles.php#Batch.FindAndReplace

希望这可以帮助别人!

谢谢,

约翰D

 @echo off set pathtofind=%~dp0 if not exist %pathtofind% echo Path does not exist&pause>nul&goto :eof cd /d %pathtofind% set path1=%cd% cd .. set path2=%cd% call set "path3=%%path1:%path2%\=%%" echo %path3% pause>nul 

3行脚本得到结果…

发现另外两种方法来实现这个目标,与其他答案不同,它不需要批量“功能”,也不需要延迟扩展,也没有Tim Peel的答案与目录深度的限制:

 @echo off SET CDIR=%~p0 SET CDIR=%CDIR:~1,-1% SET CDIR=%CDIR:\=,% SET CDIR=%CDIR: =#% FOR %%a IN (%CDIR%) DO SET "CNAME=%%a" ECHO Current directory path: %CDIR% SET CNAME=%CNAME:#= % ECHO Current directory name: %CNAME% pause 

修订:在我的新版本之后,这是一个输出示例:

 Current directory path: Documents#and#Settings,username,.sqldeveloper,tmp,my_folder,MY.again Current directory name: MY.again Press any key to continue . . . 

这意味着脚本不处理文件夹名称中的“#”或“,”,但可以调整。

附加信息:在dostips论坛上询问某人后,发现了一个更简单的方法:

 @echo off SET "CDIR=%~dp0" :: for loop requires removing trailing backslash from %~dp0 output SET "CDIR=%CDIR:~0,-1%" FOR %%i IN ("%CDIR%") DO SET "PARENTFOLDERNAME=%%~nxi" ECHO Parent folder: %PARENTFOLDERNAME% ECHO Full path: %~dp0 pause>nul 

要回到原来的海报问题:

例如,给定以下路径:C:\ Folder1 \ Folder2 \ Folder3 \ Archive.bat我希望解析出'Folder3'的值。

简单的解决方案是:

 for /D %%I in ("C:\Folder1\Folder2\Folder3\Archive.bat\..") do echo parentdir=%%~nxI 

会给'Folder3'。 文件/路径不需要存在。 当然,对于父母的父目录,或者对于上面的那个(等等)也是这样工作的。

如果任何文件夹名称中有空格,则轻微更改 – 在操作之前和之后将空格替换为“:”

 set mydir="%~p0" set mydir=%mydir:\=;% set mydir=%mydir: =:% for /F "tokens=* delims=;" %%i IN (%mydir%) DO call :LAST_FOLDER %%i goto :EOF :LAST_FOLDER if "%1"=="" ( set LAST=%LAST::= % goto :EOF ) set LAST=%1 SHIFT goto :LAST_FOLDER 

呃,伙计,真是一团糟。 这很容易,没有CD的情况下在内存中执行此操作会更快。

这将获得路径的最后两个目录。 根据需要修改它以获取任何行的最后一个标记。 我基于这个原始代码有更多的复杂性为我自己的目的。

Fyi,这可能不允许带有感叹号的路径,因为我使用的是enabledelayedexpansion,但是可以修复。

它也不会在普通的驱动器根目录下工作。 这可以通过多种方式避免。 检查输入路径或计数器,或修改令牌和检查行为等

 @echo off&setlocal enableextensions,enabledelayedexpansion call :l_truncpath "C:\Windows\temp" ---------- :l_truncpath set "_pathtail=%~1" :l_truncpathloop for /f "delims=\ tokens=1*" %%x in ("!_pathtail!") do ( if "%%y"=="" ( set "_result=!_path!\!_pathtail!" echo:!_result! exit/b ) set "_path=%%x" set "_pathtail=%%y" ) goto l_truncpathloop 

在FOR命令的批处理文件中,您需要预先加%%,并加上一个额外的%(比如%%)。

'echo%〜p0'将打印批处理文件的当前目录。

这是我们到底(更粗略一点,只能走得这么深:)

 @echo off for /f "tokens=1-10 delims=\" %%A in ('echo %~p0') do ( if NOT .%%A==. set new=%%A if NOT .%%B==. set new=%%B if NOT .%%C==. set new=%%C if NOT .%%D==. set new=%%D if NOT .%%E==. set new=%%E if NOT .%%F==. set new=%%F if NOT .%%G==. set new=%%G if NOT .%%H==. set new=%%H if NOT .%%I==. set new=%%I if NOT .%%J==. set new=%%J ) @echo %new% 

我不知道它是否是我正在使用的Windows版本(win2k3),但FOR循环没有给我任何有用的尝试遍历单个字符串。 根据我的观察(以及FOR /?信息),您将对FOR的每一行输入进行一次迭代,并且无法将其更改为在一行内进行迭代。 您可以为给定的行分成多个标记,但只是FOR循环体的一个调用。

我确实认为这些答案中的CALL:LABEL方法确实很棒。 直到看到这个,我才知道的是那个“;” 和“,”都被认为是参数分隔符。 所以一旦你用分号替换反斜杠,你可以调用你的标签并用SHIFT迭代。

所以在这里发表的东西,我有下面的解决方案。 而不是抓住最后一个文件夹的名字,我真的想找到一切,直到一些已知的目录名..这是实施下面。

 @echo off if "%1"=="" goto :USAGE set FULLPATH=%~f1 set STOPDIR=%2 set PATHROOT= :: Replace backslashes with semicolons set FULLPATH=%FULLPATH:\=;% :: Iterate through path (the semicolons cause each dir name to be a new argument) call :LOOP %FULLPATH% goto :EOF :LOOP ::Exit loop if reached the end of the path, or the stop dir if "%1"=="" (goto :EOF) if "%1"=="%STOPDIR%" (goto :EOF) ::If this is the first segment of the path, set value directly. Else append. if not defined PATHROOT (set PATHROOT=%1) else (set PATHROOT=%PATHROOT%\%1) ::shift the arguments - the next path segment becomes %i SHIFT goto :LOOP :USAGE echo Usage: echo %~0 ^<full path to parse^> ^<dir name to stop at^> echo Eg for a command: echo %~0 c:\root1\child1\child2 child2 echo The value of c:\root1\child1 would be assigned to env variable PATHROOT 

不幸的是,这只有当放在一些深度,但在山顶上有问题时,工作很好…把这个程序进入“C:\ Windows”,例如将导致…“C:\ Windows” ,不期望“Windows”。 仍然伟大的工作,仍然可以修复损坏。 我的方法是:

 @echo off set pathtofind=%~dp0 if not exist %pathtofind% echo Path does not exist&pause>nul&goto :eof cd /d %pathtofind% set path1=%cd% cd .. set path2=%cd% set path4=%~dp1 call set "path3=%%path1:%path2%\=%%" call set "path5=%%path3:%path4%*\=%%" echo %path5% pause>nul 

现在对我来说工作得很好,感谢这个想法,我一直在寻找类似的东西。

杰斯