ImmortalStrawberry
ImmortalStrawberry

Reputation: 6091

Stop batch file only processing last file?

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

Answers (1)

Magoo
Magoo

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.


addendum

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

Related Questions