Escaping an equals sign in DOS batch string replacement command
I need to replace some text in a JNLP file using a DOS batch file to tune it for the local machine.
The problem is that the search pattern contains an equals sign which is messing up the string replacement in the batch file.
I want to replace the line,
<j2se version="1.5" initial-heap-size="100M" max-heap-size="100M"/>
with specific settings for the initial and max heap sizes.
For example at the moment I have,
for /f "tokens=* delims=" %%a in (%filePath%agility.jnlp) do (
set str=%%开发者_JAVA百科a
set str=!str:initial-heap-size="100M"=initial-heap-size="%min%M"!
echo !str!>>%filePath%new.jnlp)
but the = in the search pattern is being read as part of the replacement command.
How do I escape the equals sign so it is processed as text?
The best solution is to download and install Cygwin or GNUWin32 but, if you're really limited to the standard command processor, it can get a little messy.
This is not the fastest method in the world but it's at least functional. This command file processes each line one character at a time, treating specially the case where you find the stanza you're looking for.
@echo off
set init=50M
set max=75M
setlocal enableextensions enabledelayedexpansion
for /f "tokens=* delims=" %%a in (agility.jnlp) do (
set str1=%%a
call :morph
echo !str2!>>agility_new.jnlp
echo !str2!
)
endlocal
goto :eof
:morph
set str2=
:morph1
if not "x!str1!"=="x" (
if "!str1:~0,18!"=="initial-heap-size=" (
set str2=!str2!initial-heap-size="!init!"
set str1=!str1:~24!
goto :morph1
)
if "!str1:~0,14!"=="max-heap-size=" (
set str2=!str2!max-heap-size="!max!"
set str1=!str1:~20!
goto :morph1
)
set str2=!str2!!str1:~0,1!
set str1=!str1:~1!
goto :morph1
)
goto :eof
With the input file:
<j2se version="1.5" initial-heap-size="100M" max-heap-size="100M"/>
next line
===
you end up with:
<j2se version="1.5" initial-heap-size="50M" max-heap-size="75M"/>
next line
===
One cannot simply replace (a substring with) an equal-sign, without splitting up (for-statement with "delims=="
) or trimming…
But perhaps you could go for this simpler but more confusing approach, using the following statement in your for-loop:
set str=!str:"100M" max-heap-size="%min%M" max-heap-size!
It just combines the string to replace with what comes after instead of what comes before, avoiding any equal-sign replacements entirely.
If you can pass the arguments as something else, such as double underscores, you can iterate through them and convert them to '=' in the batch file.
@rem Replace __ with = in batch files.
@rem This works around the lack of equals signs in args
@rem args contains full args string with substitutions in place
setlocal enabledelayedexpansion
:argloop
if "%~1" NEQ "" (
set str=%~1
set out=!str:__==!
set %~1=!out!
set args=!args!!out!
SHIFT
goto :argloop
)
@rem Can now run program on a line on its own with just %args%
Source: https://github.com/mlabbe/batchargs
Here's an alternative solution. If you can afford to download GNU tools, you can use sed:
C:\test>set a=200
C:\test>sed -i.bak "s/^\(.*initial-heap-size=\"\).*\( max.*\)/\1%a%\"\2/" file
精彩评论