我在Windows中运行批处理脚本。每次调用批处理脚本时,都会提供输入路径作为参数。我需要从路径中提取文件夹名称。因为我需要得到" /"的最后一个索引。从路径开始,然后从该路径获取子字符串,直到字符串结束。
假设我有一个字符串/ home / home1 / home2 / home3
我需要的输出是home3。有没有办法提取相同的。
答案 0 :(得分:2)
对于普通的DOS / Windows批处理文件,这应该有效:
set FILE="c:\foo\bar.txt"
for /F %%i in ("%FILE%") do @echo %%~ni
来自DOS BAT file equivalent to Unix basename command?
Windows PowerShell和Unix shell提供了其他替代方案。
答案 1 :(得分:1)
因此,您有一个表示文件夹路径的字符串,并且您希望路径中最右侧文件夹的名称。 CMD.EXE提供了处理文件/文件夹路径的便捷工具,因此无需搜索最后\
。
您不会说明字符串所在的位置。很可能它是1)在从CALL到批处理脚本或:函数的批处理参数中,或2)在环境变量中。我将假设一个参数,并显示一系列解决方案,每个解决方案比前一个更好(更强大)。最后,我将稍微展示一下,以适应使用环境变量。
因此,如果参数%1
包含/home/home1/home2/home3
,那么您只需要%~n1
。
但文件夹名称可以包含点,最后一个点后面的文本被视为扩展名。因此,您还需要x
修饰符来包含扩展名。例如,如果%1
包含/home.1/home.2/home.3
,则%~nx
将产生home.3
。如果没有扩展,它也可以正常工作。
但是文件夹名称可以包含像&
这样的有毒字符,因此您应该将字符串括在引号中:"%~nx1"
。如果要将结果分配给变量,则应将整个赋值括在引号中:set "folder=%~nx1"
。该值不会包含引号,因此请务必在展开变量时添加引号:"%folder%"
,否则请使用延迟展开!folder!
。
但有时人们在传递文件夹路径时会包含尾部反斜杠,如\home1\home2\home3\
中所示。尾部反斜杠肯定表示路径是指向文件夹,但%~nx1
不会产生任何结果。有一个简单的技巧,使用FOR循环和附加点来解决这个问题。
for %%F in (%1.) do set "folder=%%~nxF"
请注意,FOR变量使用与参数完全相同的修饰符。附加的点优雅地以棘手的方式解决了问题。如果有一个尾随反斜杠,则该点代表"当前"该位置的目录。扩展修饰符会自动将结果规范化为规范形式,从而产生正确的答案。但是如果没有反斜杠,它也可以工作。文件和文件夹名称不允许以点或空格结尾,扩展规范化将剥离尾随点。
还有一些其他深奥的案例涉及UNC路径和长路径,通过添加~f
修饰符将%1
转换为完整的规范路径来解决这些问题。
这是终极解决方案,应始终"始终"使用批处理参数%1
。
for %%F in ("%~f1.") do set "folder=%%~nxF"
我把'#34;总是"在引号中,因为代码可能会失败,但它需要最终用户做一些愚蠢的事情,比如传递"c:\This"^&"that\"
。在这种情况下,正确的做法就是传递"c:\This&that\"
。
请注意,传递的路径可以是卷的根,例如" c:\"。在这种情况下,结果是一个空字符串,这是正确的 - 没有文件夹名称。
如何使用环境变量
假设您有包含路径字符串的变量folderPath
。如果您知道该值不包含任何引号,并且它不是UNC或长路径,那么您只需使用:
for %%F in ("%folderPath%.") do set "folder=%%~nxF"
但是如果值已经包含引号,或者它是UNC或长路径,则可能以多种方式失败。解决方案是添加额外的FOR / F循环以及延迟扩展,以将值安全地转移到FOR变量中。然后可以像以前一样使用~f
修饰符。但路径可以包含!
字符,如果启用了延迟扩展,FOR变量扩展将删除任何!
。因此,必须在战略上切换延迟扩张。
以下是使用变量
的最终解决方案我假设延迟扩张目前已经关闭。
setlocal enableDelayedExpansion
for /f "eol=: delims=" %%A in ("!folderPath!") do (
endlocal
for %%F in ("%%~fA.") do set "folder=%%~nxF"
)
我不知道最后一个代码可能失败的任何情况。