title: Windows batch file renames filename unexplainably in FOR loop
body: <h2>Windows batch file renames filename unexplainably in FOR loop</h2>
  
  <p>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.) </p>
  
  <p><strong>Two sample filenames used for this test are:</strong></p>
  
  <pre><code>01-serious song.mp3
  02-happy song.mp3
  </code></pre>
  
  <p><strong>This section of code results in a problem:</strong></p>
  
  <pre><code>@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
  </code></pre>
  
  <p><strong>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):</strong></p>
  
  <pre><code>Artist-Artist-01-serious song.mp3
  Artist-02-happy song.mp3
  </code></pre>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p><strong>Version Two Test:</strong></p>
  
  <pre><code>@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
  </code></pre>
  
  <p><strong>Here is the resulting output shown on the CMD screen:</strong></p>
  
  <pre><code>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
  </code></pre>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p>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?</p>
  
  <p><strong>Thank you, Pete.</strong></p>