Reputation: 6091
I have the following simple batch file for renaming *.txt files and removing the first x characters
@Echo Off
for %%i in ("*.txt") do (
set fname=%%i
echo %fname%
copy %fname% %fname:~9%
)
However, it only processes the last file? If I have 4 files in there, the last file gets copied 4 times as well?
What do I need to do?
Upvotes: 0
Views: 96
Reputation: 80043
The problem is that %var% is replaced by the variable's value when the loop is first parsed, and doesn't change during execution.
Here's a demonstration which should allow you to fix your code:
@ECHO off&setlocal&CLS
ECHO Demonstrating the use of %%var%% IN a block
ECHO.
SET var=Original value
ECHO Before the block, %%var%%=%var%
FOR %%i IN (1 2 3) DO (
SET var=New value %%i
ECHO loop %%i : %%var%%=%var%
)
ECHO After the block, %%var%%=%var%
ECHO.
ECHO BECAUSE the block is first PARSED, then executed.
ECHO in the parsing process, %%var%% is replaced by its
ECHO value as it stood when the block was parsed - BEFORE execution
ECHO.
ECHO now try using a SETLOCAL ENABLEDELAYEDEXPANSION command first:
ECHO.
SETLOCAL ENABLEDELAYEDEXPANSION
SET var=Original value
ECHO Before the block, %%var%%=%var% and ^^!var^^!=!var!
FOR %%i IN (1 2 3) DO (
SET var=New value %%i
ECHO loop %%i : %%var%%=%var% BUT ^^!var^^!=!var!
)
ECHO After the block, %%var%%=%var% and ^^!var^^!=!var!
ECHO.
Oh, so many carets! An illiterate rabbit's paradise.
The caret character (^
) "escapes" the special meaning of the character which follows - except for %
which is escaped by another %
So - in the line
ECHO Before the block, %%var%%=%var%
What is echoed is "Before the block, " then a single %
, the text var
, another single %
, =
and the value of var
After SETLOCAL ENABLEDELAYEDEXPANSION
the character !
becomes a special character. so
ECHO Before the block, %%var%%=%var% and ^^!var^^!=!var!
or
ECHO loop %%i : %%var%%=%var% BUT ^^!var^^!=!var!
appends a single !
, the string var
, another single !
and =
and the run-time value of var
because at PARSE time, the ^^
is replaced by ^
and the resultant ^!
is then interpreted at EXECUTION time as a literal !
. The !var!
remains intact at PARSE time, but is replaced by the value of var
at execution time.
Upvotes: 4