批处理文件中输入字符串中字符的最后一个索引

时间:2016-09-17 05:39:17

标签: batch-file

我在Windows中运行批处理脚本。每次调用批处理脚本时,都会提供输入路径作为参数。我需要从路径中提取文件夹名称。因为我需要得到" /"的最后一个索引。从路径开始,然后从该路径获取子字符串,直到字符串结束。

假设我有一个字符串/ home / home1 / home2 / home3

我需要的输出是home3。有没有办法提取相同的。

2 个答案:

答案 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"
)

我不知道最后一个代码可能失败的任何情况。