Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Escaping exclamation marks with delayed expansion

I have a batch file I'm using to search for a piece of text and replace it with another. It works, but what's happening is that when the 'new' file is created, anything after an exclamation mark is deleted.

So original file

Hello! I have some cheese

Just becomes

Hello

Although the text I am trying to replace is fine.

I understand that since I'm using delayed expansion I need to somehow escape the exclamation marks with ^^! but can't figure out where to do this. Adding it at the echo just echoes the ^^! literally.

Any help would be appreciated.

set "rootname=Common Filename"

set "replace="old">"
set "replaced="new">"


set "source="%rootname%_unqiue_suffix.txt""
set "target=Fixed\%SOURCE%"


 setlocal enableDelayedExpansion
(
   for /F "tokens=1* delims=:" %%a in ('findstr /N "^" %source%') do (
      set "line=%%b"
      if defined line set "line=!line:%replace%=%replaced%!"
      echo(!line!
   )
) > %target%

endlocal
like image 992
SwagBag Avatar asked Oct 12 '25 05:10

SwagBag


1 Answers

To avoid loss of exclamation marks, enable delayed expansion only when it is really needed and expand normal % variables and for meta-variables only when delayed expansion is disabled:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "rootname=Common Filename"

set "replace="old">"
set "replaced="new">"

set "source=%rootname%_unqiue_suffix.txt"
set "target=Fixed\%source%"

(
    for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "%source%"') do (
        set "line=%%b"
        setlocal EnableDelayedExpansion
        if defined line set "line=!line:%replace%=%replaced%!"
        echo(!line!
        endlocal
    )
) > "%target%"

endlocal

This code still causes trouble in case the variables replace and replaced contain !-signs, because they are percent-expanded.

like image 100
aschipfl Avatar answered Oct 16 '25 08:10

aschipfl