1

I'm running a series of simulations and, because I need to edit a few files after each simulation to run the next one, I wanted to automate this process.

I already found how to search and replace a specific string with another, but what I need is to change these strings dynamically, based on a file that I wrote that has multiple replacement strings.

This is what I have so far for a basic search and replace (it's a solution I found here):

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "INTEXTFILE=Test.in"
set "OUTTEXTFILE=Test_out.in"
set "SEARCHTEXT=50kV"
set "REPLACETEXT=60kV"

for /f "delims=" %%A in ('type "%INTEXTFILE%"') do (
    set "string=%%A"
    set "modified=!string:%SEARCHTEXT%=%REPLACETEXT%!"
    echo !modified!>>"%OUTTEXTFILE%"
)

del "%INTEXTFILE%"
rename "%OUTTEXTFILE%" "%INTEXTFILE%"
endlocal

And this is what I've attempted, based on my understanding of the syntax:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "SOURCEFILE=Test.txt"
set "INTEXTFILE=Test.in"
set "OUTTEXTFILE=Test_out.in"
set "SEARCHTEXT=50kV"

for /f "delims=" %%A in ('type "%SOURCEFILE%"') do (
    set "REPLACETEXT=%%A"
    for /f "delims=" %%B in ('type "%INTEXTFILE%"') do (
        set "string=%%B"
        set "modified=!string:%SEARCHTEXT%=%REPLACETEXT%!"
        echo !modified!>>"%OUTTEXTFILE%"
    )

    set "SEARCHTEXT=%%A"
    del "%INTEXTFILE%"
    rename "%OUTTEXTFILE%" "%INTEXTFILE%"
)
endlocal

However, this simply deletes the string I'm searching for (at least when all the instructions have been executed). What am I doing wrong here?

3
  • 2
    It is because you set and read variable REPLACETEXT within the same block of code using immediate (%-)expansion rather than delayed expansion. Since, as per my understanding, Test.txt just contains a single replacement string, read it before you read Test.in), so put the closing ) of your first for /F loop before the second loop (rather than nesting the latter within the former)… Commented Mar 21, 2021 at 13:20
  • Test.txt contains 21 replacement strings. The idea is to run the simulation and save the results (using the same batch file; I excluded that code because it'd be meaningless for this problem), replace the necessary strings, and then run a new simulation. Were it just one replacement string, the solution I found would've worked just fine. However, I looked into delayed expansion and I fixed the problem. The only issue now is that the for /f searches an empty line in the .txt file. How can I get it to stop? Commented Mar 21, 2021 at 13:26
  • 2
    Oops, I overlooked the line set "SEARCHTEXT=%%A", so multiple replacement strings make sense now… Anyway, set "modified=!string:%SEARCHTEXT%=%REPLACETEXT%!" is the problem then due to immediate expansion and the fact that delayed expansion cannot be nested; however, you could use another for /F loop to achieve another layer of expansion: for /F "delims=" %%S in ("!SEARCHTEXT!=!REPLACETEXT!") do set "modified=!string:%%S!" Commented Mar 21, 2021 at 13:38

1 Answer 1

1

I am glad to hear you have something working. Another way to do this using PowerShell might be easier to code and easier to maintain in the future.

$SourceFile = '.\Test.txt'
$InTextFile = '.\Test.in'
$OutTextFile = '.\Test_out.in'
$SearchText = '50kV'

$Replacements = Get-Content -Path $SourceFile

foreach ($Replacement in $Replacements) {
    $Modified = Get-Content -Path $InTextFile -Raw
    $Modified = $Modified -replace $SearchText,$Replacement
    $Modified | Out-File -FilePath $OutTextFile -Encoding ascii

    & DoSimulation.bat

    Remove-Item -Path $InTextFile
    Move-Item -Path $OutTextFile -Destination $InTextFile
}
Sign up to request clarification or add additional context in comments.

5 Comments

After the solution aschipfl gave me, I did encounter some issues with delayed expansion because the simulation is written in Fortran, which uses exclamation marks for comments. Does PowerShell have such an issue? Also, can I create a batch file with those commands, or do I need to format them in some other way?
It would be easiest to pu this code into a .ps1 file. If you must run it from cmd.exe, use powershell -NoLogo -NoProfile -File thefile.ps1. I do not think the PowerShell and Fortran code will conflict.
I don't have to run it from CMD, it's just more convenient. Also, I just discovered that the simulation is not running as it should (just wasted 12 hours of my life running almost 200 identical simulations, go me). My guess is that the files are not being updated properly, likely related to delayed expansion. Does PowerShell have such an issue/limitation?
@Orion, PowerShell does not have delayed expansion.
Thank you. I later discovered that wasn't even the problem; it was my own calculations (for the conditions of the simulations) that were wrong. With that fixed (and the much simpler PowerShell code), it seems everything is running smoothly. Thank you and aschipfl so much for all your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.