Windows批处理文件在FOR循环中重命名文件名无法解释 [英] Windows batch file renames filename unexplainably in FOR loop

查看:794
本文介绍了Windows批处理文件在FOR循环中重命名文件名无法解释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



测试是:

  01-严肃的song.mp3 
02-快乐的song.mp3

此部分代码会导致问题:

  @echo off 
setlocal enabledelayedexpansion
:: Temporay测试变量
set str = Artist-
for %% a in(* .mp3)do(
set oldName = %% a
set newName =!str !! oldName!
ren!oldName!!newName!

endlocal

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

  -Artist-01-serious song.mp3 
Artist-02-happy song.mp3

我梳理了互联网,没有找到一个讨论这种情况发生。我讨厌说我花了约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。
回到For循环

echo。
echo For loop completed
echo!oldName!
echo!newName!
endlocal
goto:eof

:Action
echo。
echo start of Action循环
echo!oldName!
echo!newName!
ren!oldName! !newName!
echo end of Action循环

这是CMD上显示的结果输出

 开始动作循环
01-严肃的song.mp3
Artist- 01严肃的song.mp3
动作循环结束

回到for循环

动作循环开始
02-happy song.mp3
Artist-02-happy song.mp3
动作循环结束

回到for循环

动作循环开始
Artist-01-严肃的song.mp3
艺术家 - 艺术家01严肃的song.mp3
动作循环结束

回到for循环

循环完成
Artist-01严肃的song.mp3
艺术家 - Artist-01-严重的song.mp3


$ b b

这很有趣,因为它显示正确调用并返回两次的子程序。



如果我在ren语句之前加上echo,那么它会被第三次调用,在那里它显式地重命名01文件,屏幕输出显示子程序只被调用两次,但它不会重命名文件,当然。我也尝试使用move命令而不是重命名,并得到相同的问题结果。



所以,我的问题是,为什么是循环调用子程序三次,



谢谢你,Pete。

解决方案

尝试

  delims =%% a in('dir / b / ad * .mp3')do(



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



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



delims =子句确保文件名的默认解析是无效的 - 否则,文件名将被解释为一个系列of [space-separated] tokens。


Windows batch file renames filename unexplainably in FOR loop

I have a small Windows 7 batch file to rename a library of MP3 filenames. I've included only the last few lines of code in this question. It works fine except one problem with the section of code that appends a string of text (artist name) from a variable to each filename in the directory. (Once solved, my batch file will use "set /p var=" to prompt for text to fill the variable.)

Two sample filenames used for this test are:

01-serious song.mp3
02-happy song.mp3

This section of code results in a problem:

@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

The result is that the 02 file ends up with the string appended once (as intended), while the 01 filename gets the string appended twice (error):

Artist-Artist-01-serious song.mp3
Artist-02-happy song.mp3

I've combed the Internet and not found one discussion of this happening. And I hate to say that I've spent about 8 hours working on it myself. After many tests and research, I believe that the rename statement was somehow causing this.

So I changed the batch file to call a subroutine with the rename command in it, thinking it was interferring with the for statement. That still had the problem. Then I edited the batch file with echo commands as shown below to test it.

Version Two Test:

@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

Here is the resulting output shown on the CMD screen:

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

This was interesting as it showed the subroutine properly being called and returned twice. Then it somehow got called a third time, where it apparently renamed the 01 file again, appending the variable a second time.

If I put echo before the ren statement, then the screen output shows the subroutine is only called twice, but it doesn't rename the files, of course. I also tried using the move command instead of rename, and got the same problem result.

So, my question is, Why is the for loop calling the subroutine three times and making the 01 file get processed twice, and how can I make it to work as intended?

Thank you, Pete.

解决方案

Try

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

The problem is that your original syntax finds the next filename - which finds your renamed file since the new filename (with the prefix) is logically 'greater than' the old.

Using dir builds a list of filenames, and processes the list once it has been completely built - hence the list doesn't vary as the files are renamed.

The "delims=" clause ensures that the default parsing of the filename is ineffective - otherwise, the filename would be interpreted as a series of [space-separated] tokens.

这篇关于Windows批处理文件在FOR循环中重命名文件名无法解释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆