0

I have a batch file to Find and replace text string in a file with a portion of the its own file-name in multiple files within a folder using windows Batch script but it does not work and simply replace YYY with null or nothing. Any help appreciated. thank you

@echo off
SETLOCAL
SET stringtofindreplace=YYY
for %%f in (*.fmw) do (
    @echo Processing %%f...
    fOR /F "delims=" %%l IN (%%f) DO (
        SET "line=%%l"
        SET fname=%%~nf
        SET fname=!fname:~6,3!
        SETLOCAL ENABLEDELAYEDEXPANSION 
        set "x=!line:%stringtofindreplace%=%fname%!" 
        echo(!x!
        ENDLOCAL)
    )>%%~nf.txt
)
GOTO:EOF 

here is updated code that still does not work

@echo off
SETLOCAL
SET stringtofindreplace=YYY
for %%f in (*.fmw) do (
     @echo Processing %%f...
     (
     fOR /F "delims=" %%l IN (%%f) DO (
         SET "line=%%l"
         SET fname=%%~nf
         SETLOCAL ENABLEDELAYEDEXPANSION
         SET fname=!fname:~6,3!
         SET "x=!line:%stringtofindreplace%=%fname%!" 
         echo(!x!
         ENDLOCAL
         )
     )>%%~nf.txt
 )
 GOTO:EOF
user1879324
  • 5
  • 1
  • 5
  • It acts weird! when i replace %fname% with %~nf it replace YYY with file name but i want to get portion of the file name(start from position 6 and length of 3) thank you – user1879324 Mar 07 '14 at 19:36

1 Answers1

0

You have a number of problems.

1) Your name substring computation attempts to use delayed expansion within your loop before you enable it.

2) The computed replacement string cannot be expanded using normal expansion. You need delayed expansion there as well. But you cannot use delayed expansion within delayed expansion. The trick is to transfer the inner value to a FOR variable.

3) You have got an extra, unbalanced ) after ENDLOCAL. I don't think it is causing any problems with the code you have posted, but you probably should remove it.

You are also computing the name substring once for every line, when it really only need be done once per file. This isn't a bug, but it is inefficient.

Here is corrected code.

@echo off
setlocal
set stringtofindreplace=YYY
for %%f in (*.fmw) do (
  @echo Processing %%f...
  setlocal enableDelayedExpansion
  set "fname=%%~nf"
  for /f "eol=: delims=" %%A in ("!fname:~6,3!") do (
    endlocal
    for /f "delims=" %%l IN (%%f) do (
      set "line=%%l"
      setlocal enableDelayedExpansion 
      set "x=!line:%stringtofindreplace%=%%A!" 
      echo(!x!
      endlocal
    )
  )>"%%~nf.txt"
)

You still could have problems if any lines begin with ;. Also, empty lines will be stripped. Both limitations could be solved with a bit more code.

But even if you fix the limitations, it will be quite slow. It could be painfully slow if any files are large.

The code is much simpler, faster, and more reliable if you use my hybrid JScript/batch REPL.BAT utility:

@echo off
setlocal
set stringtofindreplace=YYY
for %%f in (*.fmw) do (
  @echo Processing %%f...
  setlocal enableDelayedExpansion
  set "fname=%%~nf"
  type "!fname!.fmw"|repl "%stringtofindreplace%" "!fname:~6,3!" li >"!fname!.txt"
  endlocal
)
Community
  • 1
  • 1
dbenham
  • 127,446
  • 28
  • 251
  • 390