1

So recently, I have tried to make myself a batch script to rename files by replacing a certain string by another. It is sucessful, until you add spaces. This is what my code currently looks like :

@echo off
:0
cls
set /p "str=String to replace   : "
set /p "rsw=Replace string with : "
set /p "infile=In file : "
for %%a in ("%infile%") do (
cd %%~dpa
set "fn1=%%~nxa"
call set fn2=%%fn1:%str%=%rsw%%%
ren "%%~dpa%fn1%" "%%~dpa%fn2%"
)
echo "%str%" "%rsw%"
echo "%fn1%" "%fn2%"
pause
goto 0

Solved :

I have modified my code to look like this and now it works :

@echo off
set /p "str=String to replace   : "
set /p "rsw=Replace string with : "
title Replace "%str%" with "%rsw%"
:0
cls
set /p "infile=In file : "
for %%a in ("%infile%") do (
set "wkdir=%%~dpa"
set "fn1=%%~nxa"
)
call set "fn2=%%fn1:%str%=%rsw%%%"
cd %wkdir%
ren "%fn1%" "%fn2%"
pause
goto 0

I even tried using setlocal EnableDelayedExpansion but it didn't help so I simply took the renaming process out of the for command.

The only problem that I now run into is renaming a file containing spaces in it's name.

Infers
  • 17
  • 4

1 Answers1

2

First issue: We normally assume that a batch is being run from the prompt. You appear to be using the "point, click and giggle" method (clicking a "shortcut")

Initially, a cmd instance contains no user-set variables. It is standard practice to include

setlocal

immediately after the @echo off line to establish a "local" environment. Changes made to that local environment (like establishing str etc) are removed when the batch ends.

Since you have not used this setlocal statement, any variables you have established in a run remain set for subsequent runs (if you are running from the prompt).

Next issue : the ever-faithful "delayed expansion" characteristic (see Stephan's DELAYEDEXPANSION link: https://stackoverflow.com/a/30284028/2128947 ).

You would understand from there that in your code, ren "%%~dpa%fn1%" "%%~dpa%fn2%" will be resolved using the values of fn1 and fn2 as they stood when the for was parsed, not the modified values that were set within the for block.

It could be that you are being deceived by the fact that fn1 and fn2 would retain their values when the loop back to :0 is executed, or even between invocations if you are running from the prompt where the modified values are not deleted in consequence of the absence of a setlocal.

Third issue: a ren statement may have a path specifier on its first argument, but must NOT have a path specifier on the second - only a name[.extension] is allowed.

Magoo
  • 77,302
  • 8
  • 62
  • 84