4

This seems like is should be fairly simple, but I am having trouble getting a FOR loop in DOS to correctly report the current item it is evaluating.

I have a simple DOS batch file that loops through all files in a directory and renames them. Let's say for example my directory contains the following files:

File1.txt
File2.txt
File3.txt

I want to remove the TXT extension from each file. So my batch command looks something like:

@echo off

for %%F in ("*.txt") do (
  echo %%F
  set tmpFile=%%F
  echo %tmpFile%
  set newFile=%tmpFile:~0,-4%.xml
  echo %newFile%
)

My expected output would be:

File1.txt
File1.txt
File1.xml
File2.txt
File2.txt
File2.xml
File3.txt
File3.txt
File3.xml

Instead the output is:

File1.txt
File3.txt
File3.xml
File2.txt
File3.txt
File3.xml
File3.txt
File3.txt
File3.xml

It's as if setting %%F to a variable always uses the last file in the collection.

Am I doing something wrong? Please note I know there are better ways to simply change an extension. My finished batch file will perform many more actions, but I can't seem to get past this initial step.

TroggleDorf
  • 410
  • 2
  • 8
  • 14

1 Answers1

6

It's because you are setting and accessing a variable within a for loop.

You need to use delayed expansion to access them, using !'s instead of %'s.

setlocal enabledelayedexpansion
for %%F in ("*.txt") do (
  echo %%F
  set tmpFile=%%F
  echo !tmpFile!
  set newFile=!tmpFile:~0,-4!.xml
  echo !newFile!
)
Bali C
  • 30,582
  • 35
  • 123
  • 152