I am trying to modify a certain property in my csm.properties by executing a script. I looked up a lot and in the end, came to this code.
set "search=CLASSPATH"
set "insert=CLASSPATH^=plugins^/Numbering.jar^\^:"
set "textFile="%workingPlace%bin\csm.properties""
FOR /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
FOR /f "tokens=1*delims==" %%g IN ("%%i") DO (
IF /i "%%g" == %search% (
set "line=%%i"
setlocal enabledelayedexpansion
>>"%textFile%" echo(!line:%search%=%insert%!
endlocal
)ELSE (
%%i
)
)
)
This code should read every line in my file and use =
as a delimiter. If the code gets "CLASSPATH" as property, that line should get modified.
But it seems like CLASSPATH isn't found.
This is how csm.properties looks like:
#Tue Jul 10 08:50:23 CEST 2018
JAVA_ARGS=-Xmx20000M -DLOCALCONFIG\=true -splash\:data/splash.png -Dmd.class.path\=$java.class.path -Dcom.nomagic.osgi.config.dir\=configuration -Desi.system.config\=data/application.conf -Dlogback.configurationFile\=data/logback.xml -Dsun.locale.formatasdefault\=true -Dinitial.user.language\=de
JAVA_HOME=jre1.8.0_152
BOOT_CLASSPATH=lib/xalan.jar
MAIN_CLASS=com.nomagic.osgi.launcher.ProductionFrameworkLauncher
MAC_JAVA_ARGS="-Xdock\:name\=Cameo Systems Modeler" -Xdock\:icon\=bin/md.icns -Dapple.laf.useScreenMenuBar\=true
APP_ARGS=
DEFAULT_MEMORY_SETTINGS_64=-Xmx[30%,1200,4000]M
DEFAULT_MEMORY_SETTINGS_32=-Xmx800M
CLASSPATH=lib/patch.jar\:lib/brand_api.jar
CONSOLE=false
After modifications, CLASSPATH
should look like this:
CLASSPATH=plugins/Numbering.jar\:lib/patch.jar\:lib/brand_api.jar
Insert seems needed rather than a replace.
The for loop reads each line of
%textfile%
and the nestedfor
loop delimits on the=
to store token 1 and token 2 with the remainder.If
%search%
is found, then!token1!
and!token2!
isset
the token values.set
usually can handle poison characters after it so why it is used. Expansion is delayed so poison characters are echoed to file without being expanded into the source.If
%search%
is not found, the line is set to!line!
, expansion is delayed, and then the line is echoed to file.Note:
%workingPlace%
is unknown so correct the path as needed.You can give this a go:
Similar theory, it will only replace the full string if the first token (%%i) matches
CLASSMAP
Please do not change the double quotations in the
set
commands.Here is my solution for this string replacement task using only internal commands of
cmd.exe
with exception of FINDSTR.Read my answer on How to read and print contents of text file line by line? why command FINDSTR is used just to output every line in file
csm.properties
including empty lines ignored by FOR by default with line number and:
to avoid that any line is ignored by FOR. The line number and the colon is removed by the command lineset "Line=!Line:*:=!"
.There is the environment variable
FoundInfo
undefined at top of the batch file and which is set once a line starting case-insensitive withCLASSSPATH=
is processed by the inner code of FOR loop. Every line in file after the line starting withCLASSSPATH=
is just output without further processing including empty lines.An empty line above line starting with
CLASSSPATH=
is also output withecho/
without any further processing.The first line starting case-insensitive with
CLASSPATH=
can be processed in three different ways:CLASSPATH=
.In this case the line is output as
CLASSPATH=plugins/Numbering.jar
and that's it.CLASSPATH=
and contains one or more characters, but not case-insensitive the stringplugins/Numbering.jar
. In this case the line is output within insertingplugins/Numbering.jar\:
afterCLASSPATH=
.Please note that a line with just
CLASSPATH=
and one or more trailing spaces/tabs would result also in running into second branch resulting for example in output ofCLASSPATH=plugins/Numbering.jar\:
with\:
and the trailing whitespaces at end.CLASSPATH=
and contains already case-insensitive the stringplugins/Numbering.jar
somewhere on the line.In this case the FOR loop is exited immediately with a jump to label
DeleteTempFile
without processing any further line from captured output of FINDSTR. So the last modification date of the file does not change because of nothing changed on file content. (I don't like a change last modification date on file content not really modified.)After the FOR loop is checked if there was any line starting case-insensitive with
CLASSPATH=
at all in the file. The lineCLASSPATH=plugins/Numbering.jar
is appended to the temporary file if that was not the case.Finally with temporary file definitely being different to
csm.properties
, the temporary file is moved over existing filecsm.properties
if that is possible at all and last the temporary file is deleted if it is still existing.Note 1: The solution could be easier without usage of FINDSTR if file
csm.properties
contains no empty lines or it is acceptable that empty lines are removed during the update of line withCLASSPATH=
.Note 2: The line with
CLASSPATH=
at top of filecsm.properties
reduces the process time.Summary of features of this solution:
CLASSPATH=
withplugins/Numbering.jar
somewhere on line.plugins/Numbering.jar\:
afterCLASSPATH=
only if there are other class paths (or trailing whitespaces) on this line.plugins/Numbering.jar
to existingCLASSPATH=
line not containing any other class path (and no trailing whitespaces on this line).CLASSPATH=
line withplugins/Numbering.jar
to file not containing this line at all if the file exists at least.CLASSPATH=
at beginning.VARIABLE==value
(value with equal sign at beginning) toVARIABLE=value
(equal sign at beginning removed).CLASSPATH=
and works for that reason also withclasspath=
orClassPath=
in file.;
being default of FOR's end of line option (eol).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.
del /?
echo /?
endlocal /?
findstr /?
for /?
goto /?
if /?
move /?
set /?
setlocal /?
See also Why is no string output with 'echo %var%' after using 'set var = text' on command line? and How to set environment variables with spaces? These answers explain why in most cases
set variable="value"
is not good and what is the difference toset "variable=value"
which is the preferred syntax for definition of an environment variable with a string value.See also Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files explaining how string comparison works with command IF and why the operators
EQU
andNEQ
designed primary for integer comparisons should be in general not used for comparing two strings although this is possible. The usage ofEQU
andNEQ
for string comparisons can in some cases with not double quoted strings result in an unexpected comparison result.Simpler...