的DELIMS选项指定的字符,而不是字符串列表。因此,您的FOR循环将分割标记'
或_
或b
或y
。另外,您无法知道最后一个令牌的数字是多少。你的设计是一个死路一条。
选项1
这是一个纯粹的批量解决方案,将你想要做什么。我使用替换将文件名转换为伪路径。然后轻松选取所需的名称。延迟扩展用于访问设置它的同一个循环(代码块)内的变量值。唯一棘手的部分是根据需要打开和关闭延迟扩展,以保留任何!
。如果包含!
字符的FOR变量在扩展时启用延迟扩展,则它将被损坏。
@echo off
setlocal disableDelayedExpansion
for %%F in (*_by_*.jpg) do (
%= Initialize name without extension =%
set "name=%%~nF"
%= Convert "Part1_by_Part2_by_Name" into "Part1\Part2\Name" =%
setlocal enableDelayedExpansion
for %%f in ("!name: - =\!") do (
%= Only execute endlocal on the first iteration =%
if "!!" equ "" endlocal
%= The name might contain a dot, so need name and extension =%
set "name=%%~nxf"
)
set "file=%%F"
setlocal enableDelayedExpansion
%= Hide error message if folder already exists =%
md "!name!" 2>nul
move "!file!" "!name!"
endlocal
)
选项2
的逻辑是简单的,如果使用的子程序,因为它避免了延迟扩展的问题。 CALL使代码效率较低(较慢),但这不应该成为这样的任务的问题。
@echo off
setlocal disableDelayedExpansion
for %%F in (*_by_*.jpg) do call :moveFile "%%F"
exit /b
:moveFile
set "name=%~n1"
for %%F in ("%name:_by_=\%") do set "name=%%~nxF"
md "%name%" 2>nul
move %1 "%name%"
exit /b
选项3
最简单的解决方案是使用我的JREPL.BAT utility - 混合的JScript /批执行正则表达式置换脚本。 JREPL是纯粹的脚本,可以在任何Windows XP机器上运行。
@echo off
for /f "tokens=1,2 delims=: eol=:" %%A in (
'dir /b /a-d *_by_*.jpg ^| jrepl "^.*_by_(.*)\.jpg" "$&:$1" /i'
) do (
md "%%B" 2>nul
move "%%A" "%%B"
)