Windows批处理文件在FOR循环中无法解释地重命名文件名

Pet*_*ton 2 windows cmd

Windows批处理文件在FOR循环中无法解释地重命名文件名

我有一个小的Windows 7批处理文件来重命名MP3文件名库.我在这个问题中只包含了最后几行代码.它工作正常,除了代码部分的一个问题,该部分将变量的文本字符串(艺术家名称)附加到目录中的每个文件名.(一旦解决,我的批处理文件将使用"set/p var ="来提示文本填充变量.)

用于此测试的两个示例文件名是:

01-serious song.mp3
02-happy song.mp3
Run Code Online (Sandbox Code Playgroud)

这部分代码导致了一个问题:

@echo off
setlocal enabledelayedexpansion
::Temporay test variable
set str=Artist-
for %%a in (*.mp3) do (
  set oldName=%%a
  set newName=!str!!oldName!
  ren "!oldName!" "!newName!"
)
endlocal
Run Code Online (Sandbox Code Playgroud)

结果是02文件以字符串附加一次(按预期)结束,而01文件名获取附加两次的字符串(错误):

Artist-Artist-01-serious song.mp3
Artist-02-happy song.mp3
Run Code Online (Sandbox Code Playgroud)

我已经梳理了互联网,没有找到关于这种情况的讨论.我不想说我自己花了大约8个小时来处理它.经过多次测试和研究后,我认为重命名声明在某种程度上造成了这种情况.

所以我改变了批处理文件,用其中的rename命令调用子程序,认为它干扰了for语句.那仍然有问题.然后我使用echo命令编辑批处理文件,如下所示进行测试.

第二版测试:

@echo off
setlocal enabledelayedexpansion
set str=Artist-
for %%a in (*.mp3) do (
set oldName=%%a
set newName=!str!!oldName!
  call :Action
echo.
echo back in For loop
)
echo.
echo For loop completed
echo !oldName!
echo !newName!
endlocal
goto:eof

:Action
echo.
echo start of Action loop
echo !oldName!
echo !newName!
ren "!oldName!" "!newName!"
echo end of Action loop
Run Code Online (Sandbox Code Playgroud)

以下是CMD屏幕上显示的结果输出:

start of Action loop
01-serious song.mp3
Artist-01-serious song.mp3
end of Action loop

back in For loop

start of Action loop
02-happy song.mp3
Artist-02-happy song.mp3
end of Action loop

back in For loop

start of Action loop
Artist-01-serious song.mp3
Artist-Artist-01-serious song.mp3
end of Action loop

back in For loop

For loop completed
Artist-01-serious song.mp3
Artist-Artist-01-serious song.mp3
Run Code Online (Sandbox Code Playgroud)

这很有趣,因为它显示正确调用子程序并返回两次.然后它以某种方式第三次被调用,它显然再次重命名01文件,第二次附加变量.

如果我在ren语句之前放置echo,那么屏幕输出显示子例程只被调用两次,但它当然不重命名文件.我也尝试使用move命令而不是重命名,并得到了相同的问题结果.

所以,我的问题是,为什么for循环调用子程序三次并使01文件被处理两次,我怎样才能让它按预期工作?

谢谢,皮特.

Mag*_*goo 5

尝试

for /f "delims=" %%a in (' dir /b /a-d *.mp3') do (
Run Code Online (Sandbox Code Playgroud)

问题是你的原始语法找到了下一个文件名 - 它找到你重命名的文件,因为新的文件名(带有前缀)在逻辑上"大于"旧的.

使用dir构建文件名列表,并在完成构建后处理列表 - 因此列表不会随着文件重命名而变化.

"delims="子句确保文件名的默认解析无效 - 否则,文件名将被解释为一系列[空格分隔]标记.