Replace all using batch script

2019-03-03 22:47发布

问题:

I am trying to find "tenant_id = 1234" and replace to "tenant_id = 649" in a file with many occurrences. I found below code but unable to replace when I add =/space in variable. I tried escape character as well but some how its not working. Please let me know how to achieve this requirement using batch script in .bat file.

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "INTEXTFILE=test.txt"
set "OUTTEXTFILE=test_out.txt"
set "SEARCHTEXT=tenant_id ^= 1234"
set "REPLACETEXT=tenant ^= 123456"

echo %SEARCHTEXT%

echo %REPLACETEXT%

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

回答1:

Windows7+ contains PowerShell with the RegEx based -replace operator,
so you could use it directly or invoke it from batch as a tool.

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "INTEXTFILE=test.txt"
set "SEARCHTEXT=tenant_id = 1234"
set "REPLACETEXT=tenant = 123456"

powershell -NoP -C "(Get-Content $ENV:INTEXTFILE) -Replace $ENV:SEARCHTEXT,$ENV:REPLACETEXT|Set-Content $ENV:INTEXTFILE"

In case the TEXTs contain characters .*()^$[]which would be interpreted as REs,
you can either switch to the .Replace() method (requires PSv3+)

powershell -NoP -C "(Get-Content $ENV:INTEXTFILE).Replace($ENV:SEARCHTEXT,$ENV:REPLACETEXT)|Set-Content $ENV:INTEXTFILE"

or automatically escape the TEXTs with [RegEx]::Escape()

powershell -NoP -C "(Get-Content $ENV:INTEXTFILE) -Replace [RegEx]::Escape($ENV:SEARCHTEXT),$ENV:REPLACETEXT|Set-Content $ENV:INTEXTFILE"


回答2:

This is an easy to achieve task with using JREPL.BAT written by Dave Benham which is a batch file / JScript hybrid to run a regular expression replace on a file using JScript.

@echo off
if not exist "test.txt" goto :EOF
if not exist "%~dp0jrepl.bat" goto :EOF

call "%~dp0jrepl.bat" "(tenant_id *= *)1234" "$1649" /F "test.txt" /O -

The batch file first checks if the file to modify exists at all and immediately exits if this condition is not true, see Where does GOTO :EOF return to?

The batch file JREPL.BAT must be stored in same directory as the batch file with the code above. For that reason the batch file checks next if JREPL.BAT really exists in directory of the batch file and exits if this condition is not true.

The meaning of the regular expression search string is:

  • (...) ... Find a string referenced in replace string with $1 to keep this part of found string unmodified starting with
  • tenant_id ... case-sensitive string tenant_id
  •  * ... with 0 or more spaces
  • = ... and an equal sign
  •  * ... and once more 0 or more spaces
  • 1234 ... and the characters 1234.

The replace string back-references the found string starting with tenant_id and ending before number 1234 with $1 and replaces 1234 by 649.

It would be also possible to use the regular expression \d+ instead of 1234 in search string to find any number with one or more digits.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /? ... explains also %~dp0 ... drive and path of argument 0 which is the batch file path always ending with a backslash.
  • echo /?
  • goto /?
  • if /?
  • jrepl.bat /?