Modify a string in a .properties file with batch











up vote
0
down vote

favorite












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%bincsm.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, CLASSPATHshould look like this:



CLASSPATH=plugins/Numbering.jar:lib/patch.jar:lib/brand_api.jar









share|improve this question
























  • Unfortunately I am not allowed to use powershell. So pipelining the results to a new file and overriding the old file with the latest one, should do the work, I hope?
    – dnsiv
    Nov 15 at 12:41










  • So, If I use my delims and tokens on the first loop, will the result be the same?
    – dnsiv
    Nov 15 at 12:41










  • I can make batch work, but it will need to write to a new file, then delete old and rename the newfile.. same result you want.
    – Gerhard Barnard
    Nov 15 at 12:42










  • I would love to see that solution of yours.
    – dnsiv
    Nov 15 at 12:45










  • Also about my 2 for loops. I think, I need them because of line ) ELSE ( %%i ). If I dont have those 2 loops %%i would just return the string before =
    – dnsiv
    Nov 15 at 12:45

















up vote
0
down vote

favorite












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%bincsm.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, CLASSPATHshould look like this:



CLASSPATH=plugins/Numbering.jar:lib/patch.jar:lib/brand_api.jar









share|improve this question
























  • Unfortunately I am not allowed to use powershell. So pipelining the results to a new file and overriding the old file with the latest one, should do the work, I hope?
    – dnsiv
    Nov 15 at 12:41










  • So, If I use my delims and tokens on the first loop, will the result be the same?
    – dnsiv
    Nov 15 at 12:41










  • I can make batch work, but it will need to write to a new file, then delete old and rename the newfile.. same result you want.
    – Gerhard Barnard
    Nov 15 at 12:42










  • I would love to see that solution of yours.
    – dnsiv
    Nov 15 at 12:45










  • Also about my 2 for loops. I think, I need them because of line ) ELSE ( %%i ). If I dont have those 2 loops %%i would just return the string before =
    – dnsiv
    Nov 15 at 12:45















up vote
0
down vote

favorite









up vote
0
down vote

favorite











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%bincsm.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, CLASSPATHshould look like this:



CLASSPATH=plugins/Numbering.jar:lib/patch.jar:lib/brand_api.jar









share|improve this question















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%bincsm.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, CLASSPATHshould look like this:



CLASSPATH=plugins/Numbering.jar:lib/patch.jar:lib/brand_api.jar






batch-file cmd insert






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 15 at 15:53

























asked Nov 15 at 12:28









dnsiv

28715




28715












  • Unfortunately I am not allowed to use powershell. So pipelining the results to a new file and overriding the old file with the latest one, should do the work, I hope?
    – dnsiv
    Nov 15 at 12:41










  • So, If I use my delims and tokens on the first loop, will the result be the same?
    – dnsiv
    Nov 15 at 12:41










  • I can make batch work, but it will need to write to a new file, then delete old and rename the newfile.. same result you want.
    – Gerhard Barnard
    Nov 15 at 12:42










  • I would love to see that solution of yours.
    – dnsiv
    Nov 15 at 12:45










  • Also about my 2 for loops. I think, I need them because of line ) ELSE ( %%i ). If I dont have those 2 loops %%i would just return the string before =
    – dnsiv
    Nov 15 at 12:45




















  • Unfortunately I am not allowed to use powershell. So pipelining the results to a new file and overriding the old file with the latest one, should do the work, I hope?
    – dnsiv
    Nov 15 at 12:41










  • So, If I use my delims and tokens on the first loop, will the result be the same?
    – dnsiv
    Nov 15 at 12:41










  • I can make batch work, but it will need to write to a new file, then delete old and rename the newfile.. same result you want.
    – Gerhard Barnard
    Nov 15 at 12:42










  • I would love to see that solution of yours.
    – dnsiv
    Nov 15 at 12:45










  • Also about my 2 for loops. I think, I need them because of line ) ELSE ( %%i ). If I dont have those 2 loops %%i would just return the string before =
    – dnsiv
    Nov 15 at 12:45


















Unfortunately I am not allowed to use powershell. So pipelining the results to a new file and overriding the old file with the latest one, should do the work, I hope?
– dnsiv
Nov 15 at 12:41




Unfortunately I am not allowed to use powershell. So pipelining the results to a new file and overriding the old file with the latest one, should do the work, I hope?
– dnsiv
Nov 15 at 12:41












So, If I use my delims and tokens on the first loop, will the result be the same?
– dnsiv
Nov 15 at 12:41




So, If I use my delims and tokens on the first loop, will the result be the same?
– dnsiv
Nov 15 at 12:41












I can make batch work, but it will need to write to a new file, then delete old and rename the newfile.. same result you want.
– Gerhard Barnard
Nov 15 at 12:42




I can make batch work, but it will need to write to a new file, then delete old and rename the newfile.. same result you want.
– Gerhard Barnard
Nov 15 at 12:42












I would love to see that solution of yours.
– dnsiv
Nov 15 at 12:45




I would love to see that solution of yours.
– dnsiv
Nov 15 at 12:45












Also about my 2 for loops. I think, I need them because of line ) ELSE ( %%i ). If I dont have those 2 loops %%i would just return the string before =
– dnsiv
Nov 15 at 12:45






Also about my 2 for loops. I think, I need them because of line ) ELSE ( %%i ). If I dont have those 2 loops %%i would just return the string before =
– dnsiv
Nov 15 at 12:45














4 Answers
4






active

oldest

votes

















up vote
2
down vote



accepted










Simpler...



@echo OFF
setlocal

set "search=CLASSPATH"
set "insert=plugins/Numbering.jar:"

set "textFile=%workingPlace%bincsm.properties"

(FOR /f "usebackq tokens=1* delims==" %%i in ("%textFile%") do (
if "%%i" equ "%search%" (
echo %search%=%insert%%%j
) else if "%%j" neq "" (
echo %%i=%%j
) else (
echo %%i
)
)) > temp.tmp

move /Y temp.tmp "%textFile%"





share|improve this answer























  • This might work this way, but I can't hardcode :lib/patch.jar:lib/brand_api.jar as the classpath varies from user to user. I am writing this script for multiple people
    – dnsiv
    Nov 15 at 15:06










  • Just fixed this point... So, you really are not "replacing", but "inserting" a new value, isn't it?
    – Aacini
    Nov 15 at 15:07












  • Exactly. I am executing your code right now, but after execution the whole file is empty. So I guess there is still something wrong
    – dnsiv
    Nov 15 at 15:21










  • Remove the move command and the > temp.tmp part and confirm that the output is correct...
    – Aacini
    Nov 15 at 15:24






  • 1




    ... like I did in my set "textFile=%workingPlace%bincsm.properties" command...
    – Aacini
    Nov 15 at 15:41


















up vote
1
down vote













You can give this a go:



@echo off
setlocal enableextensions disabledelayedexpansion

set "replace=plugins^/Numbering.jar^^:"
set "textFile=%workingPlace%bincsm.properties""

for /f %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
set "line=%%i"
for /f "tokens=1* delims==" %%a in ("%%i") do (
if "%%a"=="CLASSPATH" (
setlocal enabledelayedexpansion
>>"%textFile%" echo(!line!%replace%
) else (
setlocal enabledelayedexpansion
>>"%textFile%" echo(!line!
endlocal
)
)
)


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.






share|improve this answer























  • Unfortunately I am getting a syntax error as output
    – dnsiv
    Nov 15 at 14:11










  • And what is declared as %%j ?
    – dnsiv
    Nov 15 at 14:14










  • Please copy and try again
    – Gerhard Barnard
    Nov 15 at 14:14










  • %%j is the value after = for each line
    – Gerhard Barnard
    Nov 15 at 14:16










  • Well.. it kinda worked, but now everything else from CLASSPATH has been removed. I just wanted to add a new string to CLASSPATH
    – dnsiv
    Nov 15 at 14:29


















up vote
1
down vote













Here is my solution for this string replacement task using only internal commands of cmd.exe with exception of FINDSTR.



@echo off
setlocal EnableExtensions DisableDelayedExpansion

if not defined workingPlace set "workingPlace=%~dp0"
set "TextFile=%workingPlace%bincsm.properties"
if not exist "%TextFile%" goto EndBatch

set "TempFile=%TEMP%csm.properties.tmp"
set "FoundInfo="

(for /F delims^=^ eol^= %%I in ('%SystemRoot%System32findstr.exe /N "^" "%TextFile%"') do (
set "Line=%%I"
setlocal EnableDelayedExpansion
set "Line=!Line:*:=!"
if not defined FoundInfo (
if defined Line (
if /I "!Line:~0,10!" == "CLASSPATH=" (
if /I "!Line!" == "CLASSPATH=" (
echo !Line!plugins/Numbering.jar
endlocal
set "FoundInfo=1"
) else if "!Line:plugins/Numbering.jar=!" == "!Line!" (
set "Line=!Line:~0,10!plugins/Numbering.jar:!Line:~10!"
echo !Line!
endlocal
set "FoundInfo=1"
) else (
endlocal
goto DeleteTempFile
)
) else (
echo(!Line!
endlocal
)
) else (
echo/
endlocal
)
) else (
echo(!Line!
endlocal
)
))>"%TempFile%"

if not defined FoundInfo echo CLASSPATH=plugins/Numbering.jar>>"%TempFile%"
move /Y "%TempFile%" "%TextFile%"

:DeleteTempFile
if exist "%TempFile%" del "%TempFile%"

:EndBatch
endlocal


Read my answer on ow 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 line set "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 with CLASSSPATH= is processed by the inner code of FOR loop. Every line in file after the line starting with CLASSSPATH= is just output without further processing including empty lines.



An empty line above line starting with CLASSSPATH= is also output with echo/ without any further processing.



The first line starting case-insensitive with CLASSPATH= can be processed in three different ways:




  1. The line contains just CLASSPATH=.

    In this case the line is output as CLASSPATH=plugins/Numbering.jar and that's it.

  2. The line starts with CLASSPATH= and contains one or more characters, but not case-insensitive the string plugins/Numbering.jar.
    In this case the line is output within inserting plugins/Numbering.jar: after CLASSPATH=.

    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 of CLASSPATH=plugins/Numbering.jar:  with : and the trailing whitespaces at end.

  3. The line starts with CLASSPATH= and contains already case-insensitive the string plugins/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 line CLASSPATH=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 file csm.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 with CLASSPATH=.



Note 2: The line with CLASSPATH= at top of file csm.properties reduces the process time.



Summary of features of this solution:




  1. Does not modify the text file on containing already CLASSPATH= with plugins/Numbering.jar somewhere on line.

  2. Inserts plugins/Numbering.jar: after CLASSPATH= only if there are other class paths (or trailing whitespaces) on this line.

  3. Appends plugins/Numbering.jar to existing CLASSPATH= line not containing any other class path (and no trailing whitespaces on this line).

  4. Appends entire CLASSPATH= line with plugins/Numbering.jar to file not containing this line at all if the file exists at least.

  5. Keeps empty lines in text file and so modifies really only line with CLASSPATH= at beginning.

  6. Does not modify lines with VARIABLE==value (value with equal sign at beginning) to VARIABLE=value (equal sign at beginning removed).

  7. Does not modify spelling of CLASSPATH= and works for that reason also with classpath= or ClassPath= in file.

  8. Does not remove lines starting with ; 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 to set "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 and NEQ designed primary for integer comparisons should be in general not used for comparing two strings although this is possible. The usage of EQU and NEQ for string comparisons can in some cases with not double quoted strings result in an unexpected comparison result.






share|improve this answer






























    up vote
    0
    down vote













    @echo off
    setlocal disabledelayedexpansion

    set "search=CLASSPATH"
    set "insert=plugins/Numbering.jar:"

    set "textFile=%workingPlace%bincsm.properties"

    for /f "usebackq delims=" %%i in ("%textFile%") do (
    for /f "tokens=1* delims==" %%g in ("%%i") do (
    if /i "%%g" == "%search%" (
    set "token1=%%g"
    set "token2=%%h"
    setlocal enabledelayedexpansion
    >> "%textFile%.tmp" echo(!search!=!insert!!token2!
    endlocal
    ) else (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >> "%textFile%.tmp" echo(!line!
    endlocal
    )
    )
    )

    move "%textFile%" "%textFile%.bak" && move "%textFile%.tmp" "%textFile%"


    Insert seems needed rather than a replace.



    The for loop reads each line of %textfile% and the nested for loop
    delimits on the = to store token 1 and token 2 with the remainder.



    If %search% is found, then !token1! and !token2! is set 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.






    share|improve this answer





















      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53319538%2fmodify-a-string-in-a-properties-file-with-batch%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      2
      down vote



      accepted










      Simpler...



      @echo OFF
      setlocal

      set "search=CLASSPATH"
      set "insert=plugins/Numbering.jar:"

      set "textFile=%workingPlace%bincsm.properties"

      (FOR /f "usebackq tokens=1* delims==" %%i in ("%textFile%") do (
      if "%%i" equ "%search%" (
      echo %search%=%insert%%%j
      ) else if "%%j" neq "" (
      echo %%i=%%j
      ) else (
      echo %%i
      )
      )) > temp.tmp

      move /Y temp.tmp "%textFile%"





      share|improve this answer























      • This might work this way, but I can't hardcode :lib/patch.jar:lib/brand_api.jar as the classpath varies from user to user. I am writing this script for multiple people
        – dnsiv
        Nov 15 at 15:06










      • Just fixed this point... So, you really are not "replacing", but "inserting" a new value, isn't it?
        – Aacini
        Nov 15 at 15:07












      • Exactly. I am executing your code right now, but after execution the whole file is empty. So I guess there is still something wrong
        – dnsiv
        Nov 15 at 15:21










      • Remove the move command and the > temp.tmp part and confirm that the output is correct...
        – Aacini
        Nov 15 at 15:24






      • 1




        ... like I did in my set "textFile=%workingPlace%bincsm.properties" command...
        – Aacini
        Nov 15 at 15:41















      up vote
      2
      down vote



      accepted










      Simpler...



      @echo OFF
      setlocal

      set "search=CLASSPATH"
      set "insert=plugins/Numbering.jar:"

      set "textFile=%workingPlace%bincsm.properties"

      (FOR /f "usebackq tokens=1* delims==" %%i in ("%textFile%") do (
      if "%%i" equ "%search%" (
      echo %search%=%insert%%%j
      ) else if "%%j" neq "" (
      echo %%i=%%j
      ) else (
      echo %%i
      )
      )) > temp.tmp

      move /Y temp.tmp "%textFile%"





      share|improve this answer























      • This might work this way, but I can't hardcode :lib/patch.jar:lib/brand_api.jar as the classpath varies from user to user. I am writing this script for multiple people
        – dnsiv
        Nov 15 at 15:06










      • Just fixed this point... So, you really are not "replacing", but "inserting" a new value, isn't it?
        – Aacini
        Nov 15 at 15:07












      • Exactly. I am executing your code right now, but after execution the whole file is empty. So I guess there is still something wrong
        – dnsiv
        Nov 15 at 15:21










      • Remove the move command and the > temp.tmp part and confirm that the output is correct...
        – Aacini
        Nov 15 at 15:24






      • 1




        ... like I did in my set "textFile=%workingPlace%bincsm.properties" command...
        – Aacini
        Nov 15 at 15:41













      up vote
      2
      down vote



      accepted







      up vote
      2
      down vote



      accepted






      Simpler...



      @echo OFF
      setlocal

      set "search=CLASSPATH"
      set "insert=plugins/Numbering.jar:"

      set "textFile=%workingPlace%bincsm.properties"

      (FOR /f "usebackq tokens=1* delims==" %%i in ("%textFile%") do (
      if "%%i" equ "%search%" (
      echo %search%=%insert%%%j
      ) else if "%%j" neq "" (
      echo %%i=%%j
      ) else (
      echo %%i
      )
      )) > temp.tmp

      move /Y temp.tmp "%textFile%"





      share|improve this answer














      Simpler...



      @echo OFF
      setlocal

      set "search=CLASSPATH"
      set "insert=plugins/Numbering.jar:"

      set "textFile=%workingPlace%bincsm.properties"

      (FOR /f "usebackq tokens=1* delims==" %%i in ("%textFile%") do (
      if "%%i" equ "%search%" (
      echo %search%=%insert%%%j
      ) else if "%%j" neq "" (
      echo %%i=%%j
      ) else (
      echo %%i
      )
      )) > temp.tmp

      move /Y temp.tmp "%textFile%"






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 15 at 15:06

























      answered Nov 15 at 14:57









      Aacini

      50.8k75173




      50.8k75173












      • This might work this way, but I can't hardcode :lib/patch.jar:lib/brand_api.jar as the classpath varies from user to user. I am writing this script for multiple people
        – dnsiv
        Nov 15 at 15:06










      • Just fixed this point... So, you really are not "replacing", but "inserting" a new value, isn't it?
        – Aacini
        Nov 15 at 15:07












      • Exactly. I am executing your code right now, but after execution the whole file is empty. So I guess there is still something wrong
        – dnsiv
        Nov 15 at 15:21










      • Remove the move command and the > temp.tmp part and confirm that the output is correct...
        – Aacini
        Nov 15 at 15:24






      • 1




        ... like I did in my set "textFile=%workingPlace%bincsm.properties" command...
        – Aacini
        Nov 15 at 15:41


















      • This might work this way, but I can't hardcode :lib/patch.jar:lib/brand_api.jar as the classpath varies from user to user. I am writing this script for multiple people
        – dnsiv
        Nov 15 at 15:06










      • Just fixed this point... So, you really are not "replacing", but "inserting" a new value, isn't it?
        – Aacini
        Nov 15 at 15:07












      • Exactly. I am executing your code right now, but after execution the whole file is empty. So I guess there is still something wrong
        – dnsiv
        Nov 15 at 15:21










      • Remove the move command and the > temp.tmp part and confirm that the output is correct...
        – Aacini
        Nov 15 at 15:24






      • 1




        ... like I did in my set "textFile=%workingPlace%bincsm.properties" command...
        – Aacini
        Nov 15 at 15:41
















      This might work this way, but I can't hardcode :lib/patch.jar:lib/brand_api.jar as the classpath varies from user to user. I am writing this script for multiple people
      – dnsiv
      Nov 15 at 15:06




      This might work this way, but I can't hardcode :lib/patch.jar:lib/brand_api.jar as the classpath varies from user to user. I am writing this script for multiple people
      – dnsiv
      Nov 15 at 15:06












      Just fixed this point... So, you really are not "replacing", but "inserting" a new value, isn't it?
      – Aacini
      Nov 15 at 15:07






      Just fixed this point... So, you really are not "replacing", but "inserting" a new value, isn't it?
      – Aacini
      Nov 15 at 15:07














      Exactly. I am executing your code right now, but after execution the whole file is empty. So I guess there is still something wrong
      – dnsiv
      Nov 15 at 15:21




      Exactly. I am executing your code right now, but after execution the whole file is empty. So I guess there is still something wrong
      – dnsiv
      Nov 15 at 15:21












      Remove the move command and the > temp.tmp part and confirm that the output is correct...
      – Aacini
      Nov 15 at 15:24




      Remove the move command and the > temp.tmp part and confirm that the output is correct...
      – Aacini
      Nov 15 at 15:24




      1




      1




      ... like I did in my set "textFile=%workingPlace%bincsm.properties" command...
      – Aacini
      Nov 15 at 15:41




      ... like I did in my set "textFile=%workingPlace%bincsm.properties" command...
      – Aacini
      Nov 15 at 15:41












      up vote
      1
      down vote













      You can give this a go:



      @echo off
      setlocal enableextensions disabledelayedexpansion

      set "replace=plugins^/Numbering.jar^^:"
      set "textFile=%workingPlace%bincsm.properties""

      for /f %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
      set "line=%%i"
      for /f "tokens=1* delims==" %%a in ("%%i") do (
      if "%%a"=="CLASSPATH" (
      setlocal enabledelayedexpansion
      >>"%textFile%" echo(!line!%replace%
      ) else (
      setlocal enabledelayedexpansion
      >>"%textFile%" echo(!line!
      endlocal
      )
      )
      )


      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.






      share|improve this answer























      • Unfortunately I am getting a syntax error as output
        – dnsiv
        Nov 15 at 14:11










      • And what is declared as %%j ?
        – dnsiv
        Nov 15 at 14:14










      • Please copy and try again
        – Gerhard Barnard
        Nov 15 at 14:14










      • %%j is the value after = for each line
        – Gerhard Barnard
        Nov 15 at 14:16










      • Well.. it kinda worked, but now everything else from CLASSPATH has been removed. I just wanted to add a new string to CLASSPATH
        – dnsiv
        Nov 15 at 14:29















      up vote
      1
      down vote













      You can give this a go:



      @echo off
      setlocal enableextensions disabledelayedexpansion

      set "replace=plugins^/Numbering.jar^^:"
      set "textFile=%workingPlace%bincsm.properties""

      for /f %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
      set "line=%%i"
      for /f "tokens=1* delims==" %%a in ("%%i") do (
      if "%%a"=="CLASSPATH" (
      setlocal enabledelayedexpansion
      >>"%textFile%" echo(!line!%replace%
      ) else (
      setlocal enabledelayedexpansion
      >>"%textFile%" echo(!line!
      endlocal
      )
      )
      )


      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.






      share|improve this answer























      • Unfortunately I am getting a syntax error as output
        – dnsiv
        Nov 15 at 14:11










      • And what is declared as %%j ?
        – dnsiv
        Nov 15 at 14:14










      • Please copy and try again
        – Gerhard Barnard
        Nov 15 at 14:14










      • %%j is the value after = for each line
        – Gerhard Barnard
        Nov 15 at 14:16










      • Well.. it kinda worked, but now everything else from CLASSPATH has been removed. I just wanted to add a new string to CLASSPATH
        – dnsiv
        Nov 15 at 14:29













      up vote
      1
      down vote










      up vote
      1
      down vote









      You can give this a go:



      @echo off
      setlocal enableextensions disabledelayedexpansion

      set "replace=plugins^/Numbering.jar^^:"
      set "textFile=%workingPlace%bincsm.properties""

      for /f %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
      set "line=%%i"
      for /f "tokens=1* delims==" %%a in ("%%i") do (
      if "%%a"=="CLASSPATH" (
      setlocal enabledelayedexpansion
      >>"%textFile%" echo(!line!%replace%
      ) else (
      setlocal enabledelayedexpansion
      >>"%textFile%" echo(!line!
      endlocal
      )
      )
      )


      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.






      share|improve this answer














      You can give this a go:



      @echo off
      setlocal enableextensions disabledelayedexpansion

      set "replace=plugins^/Numbering.jar^^:"
      set "textFile=%workingPlace%bincsm.properties""

      for /f %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
      set "line=%%i"
      for /f "tokens=1* delims==" %%a in ("%%i") do (
      if "%%a"=="CLASSPATH" (
      setlocal enabledelayedexpansion
      >>"%textFile%" echo(!line!%replace%
      ) else (
      setlocal enabledelayedexpansion
      >>"%textFile%" echo(!line!
      endlocal
      )
      )
      )


      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.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 15 at 20:04

























      answered Nov 15 at 14:03









      Gerhard Barnard

      6,90631131




      6,90631131












      • Unfortunately I am getting a syntax error as output
        – dnsiv
        Nov 15 at 14:11










      • And what is declared as %%j ?
        – dnsiv
        Nov 15 at 14:14










      • Please copy and try again
        – Gerhard Barnard
        Nov 15 at 14:14










      • %%j is the value after = for each line
        – Gerhard Barnard
        Nov 15 at 14:16










      • Well.. it kinda worked, but now everything else from CLASSPATH has been removed. I just wanted to add a new string to CLASSPATH
        – dnsiv
        Nov 15 at 14:29


















      • Unfortunately I am getting a syntax error as output
        – dnsiv
        Nov 15 at 14:11










      • And what is declared as %%j ?
        – dnsiv
        Nov 15 at 14:14










      • Please copy and try again
        – Gerhard Barnard
        Nov 15 at 14:14










      • %%j is the value after = for each line
        – Gerhard Barnard
        Nov 15 at 14:16










      • Well.. it kinda worked, but now everything else from CLASSPATH has been removed. I just wanted to add a new string to CLASSPATH
        – dnsiv
        Nov 15 at 14:29
















      Unfortunately I am getting a syntax error as output
      – dnsiv
      Nov 15 at 14:11




      Unfortunately I am getting a syntax error as output
      – dnsiv
      Nov 15 at 14:11












      And what is declared as %%j ?
      – dnsiv
      Nov 15 at 14:14




      And what is declared as %%j ?
      – dnsiv
      Nov 15 at 14:14












      Please copy and try again
      – Gerhard Barnard
      Nov 15 at 14:14




      Please copy and try again
      – Gerhard Barnard
      Nov 15 at 14:14












      %%j is the value after = for each line
      – Gerhard Barnard
      Nov 15 at 14:16




      %%j is the value after = for each line
      – Gerhard Barnard
      Nov 15 at 14:16












      Well.. it kinda worked, but now everything else from CLASSPATH has been removed. I just wanted to add a new string to CLASSPATH
      – dnsiv
      Nov 15 at 14:29




      Well.. it kinda worked, but now everything else from CLASSPATH has been removed. I just wanted to add a new string to CLASSPATH
      – dnsiv
      Nov 15 at 14:29










      up vote
      1
      down vote













      Here is my solution for this string replacement task using only internal commands of cmd.exe with exception of FINDSTR.



      @echo off
      setlocal EnableExtensions DisableDelayedExpansion

      if not defined workingPlace set "workingPlace=%~dp0"
      set "TextFile=%workingPlace%bincsm.properties"
      if not exist "%TextFile%" goto EndBatch

      set "TempFile=%TEMP%csm.properties.tmp"
      set "FoundInfo="

      (for /F delims^=^ eol^= %%I in ('%SystemRoot%System32findstr.exe /N "^" "%TextFile%"') do (
      set "Line=%%I"
      setlocal EnableDelayedExpansion
      set "Line=!Line:*:=!"
      if not defined FoundInfo (
      if defined Line (
      if /I "!Line:~0,10!" == "CLASSPATH=" (
      if /I "!Line!" == "CLASSPATH=" (
      echo !Line!plugins/Numbering.jar
      endlocal
      set "FoundInfo=1"
      ) else if "!Line:plugins/Numbering.jar=!" == "!Line!" (
      set "Line=!Line:~0,10!plugins/Numbering.jar:!Line:~10!"
      echo !Line!
      endlocal
      set "FoundInfo=1"
      ) else (
      endlocal
      goto DeleteTempFile
      )
      ) else (
      echo(!Line!
      endlocal
      )
      ) else (
      echo/
      endlocal
      )
      ) else (
      echo(!Line!
      endlocal
      )
      ))>"%TempFile%"

      if not defined FoundInfo echo CLASSPATH=plugins/Numbering.jar>>"%TempFile%"
      move /Y "%TempFile%" "%TextFile%"

      :DeleteTempFile
      if exist "%TempFile%" del "%TempFile%"

      :EndBatch
      endlocal


      Read my answer on ow 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 line set "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 with CLASSSPATH= is processed by the inner code of FOR loop. Every line in file after the line starting with CLASSSPATH= is just output without further processing including empty lines.



      An empty line above line starting with CLASSSPATH= is also output with echo/ without any further processing.



      The first line starting case-insensitive with CLASSPATH= can be processed in three different ways:




      1. The line contains just CLASSPATH=.

        In this case the line is output as CLASSPATH=plugins/Numbering.jar and that's it.

      2. The line starts with CLASSPATH= and contains one or more characters, but not case-insensitive the string plugins/Numbering.jar.
        In this case the line is output within inserting plugins/Numbering.jar: after CLASSPATH=.

        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 of CLASSPATH=plugins/Numbering.jar:  with : and the trailing whitespaces at end.

      3. The line starts with CLASSPATH= and contains already case-insensitive the string plugins/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 line CLASSPATH=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 file csm.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 with CLASSPATH=.



      Note 2: The line with CLASSPATH= at top of file csm.properties reduces the process time.



      Summary of features of this solution:




      1. Does not modify the text file on containing already CLASSPATH= with plugins/Numbering.jar somewhere on line.

      2. Inserts plugins/Numbering.jar: after CLASSPATH= only if there are other class paths (or trailing whitespaces) on this line.

      3. Appends plugins/Numbering.jar to existing CLASSPATH= line not containing any other class path (and no trailing whitespaces on this line).

      4. Appends entire CLASSPATH= line with plugins/Numbering.jar to file not containing this line at all if the file exists at least.

      5. Keeps empty lines in text file and so modifies really only line with CLASSPATH= at beginning.

      6. Does not modify lines with VARIABLE==value (value with equal sign at beginning) to VARIABLE=value (equal sign at beginning removed).

      7. Does not modify spelling of CLASSPATH= and works for that reason also with classpath= or ClassPath= in file.

      8. Does not remove lines starting with ; 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 to set "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 and NEQ designed primary for integer comparisons should be in general not used for comparing two strings although this is possible. The usage of EQU and NEQ for string comparisons can in some cases with not double quoted strings result in an unexpected comparison result.






      share|improve this answer



























        up vote
        1
        down vote













        Here is my solution for this string replacement task using only internal commands of cmd.exe with exception of FINDSTR.



        @echo off
        setlocal EnableExtensions DisableDelayedExpansion

        if not defined workingPlace set "workingPlace=%~dp0"
        set "TextFile=%workingPlace%bincsm.properties"
        if not exist "%TextFile%" goto EndBatch

        set "TempFile=%TEMP%csm.properties.tmp"
        set "FoundInfo="

        (for /F delims^=^ eol^= %%I in ('%SystemRoot%System32findstr.exe /N "^" "%TextFile%"') do (
        set "Line=%%I"
        setlocal EnableDelayedExpansion
        set "Line=!Line:*:=!"
        if not defined FoundInfo (
        if defined Line (
        if /I "!Line:~0,10!" == "CLASSPATH=" (
        if /I "!Line!" == "CLASSPATH=" (
        echo !Line!plugins/Numbering.jar
        endlocal
        set "FoundInfo=1"
        ) else if "!Line:plugins/Numbering.jar=!" == "!Line!" (
        set "Line=!Line:~0,10!plugins/Numbering.jar:!Line:~10!"
        echo !Line!
        endlocal
        set "FoundInfo=1"
        ) else (
        endlocal
        goto DeleteTempFile
        )
        ) else (
        echo(!Line!
        endlocal
        )
        ) else (
        echo/
        endlocal
        )
        ) else (
        echo(!Line!
        endlocal
        )
        ))>"%TempFile%"

        if not defined FoundInfo echo CLASSPATH=plugins/Numbering.jar>>"%TempFile%"
        move /Y "%TempFile%" "%TextFile%"

        :DeleteTempFile
        if exist "%TempFile%" del "%TempFile%"

        :EndBatch
        endlocal


        Read my answer on ow 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 line set "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 with CLASSSPATH= is processed by the inner code of FOR loop. Every line in file after the line starting with CLASSSPATH= is just output without further processing including empty lines.



        An empty line above line starting with CLASSSPATH= is also output with echo/ without any further processing.



        The first line starting case-insensitive with CLASSPATH= can be processed in three different ways:




        1. The line contains just CLASSPATH=.

          In this case the line is output as CLASSPATH=plugins/Numbering.jar and that's it.

        2. The line starts with CLASSPATH= and contains one or more characters, but not case-insensitive the string plugins/Numbering.jar.
          In this case the line is output within inserting plugins/Numbering.jar: after CLASSPATH=.

          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 of CLASSPATH=plugins/Numbering.jar:  with : and the trailing whitespaces at end.

        3. The line starts with CLASSPATH= and contains already case-insensitive the string plugins/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 line CLASSPATH=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 file csm.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 with CLASSPATH=.



        Note 2: The line with CLASSPATH= at top of file csm.properties reduces the process time.



        Summary of features of this solution:




        1. Does not modify the text file on containing already CLASSPATH= with plugins/Numbering.jar somewhere on line.

        2. Inserts plugins/Numbering.jar: after CLASSPATH= only if there are other class paths (or trailing whitespaces) on this line.

        3. Appends plugins/Numbering.jar to existing CLASSPATH= line not containing any other class path (and no trailing whitespaces on this line).

        4. Appends entire CLASSPATH= line with plugins/Numbering.jar to file not containing this line at all if the file exists at least.

        5. Keeps empty lines in text file and so modifies really only line with CLASSPATH= at beginning.

        6. Does not modify lines with VARIABLE==value (value with equal sign at beginning) to VARIABLE=value (equal sign at beginning removed).

        7. Does not modify spelling of CLASSPATH= and works for that reason also with classpath= or ClassPath= in file.

        8. Does not remove lines starting with ; 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 to set "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 and NEQ designed primary for integer comparisons should be in general not used for comparing two strings although this is possible. The usage of EQU and NEQ for string comparisons can in some cases with not double quoted strings result in an unexpected comparison result.






        share|improve this answer

























          up vote
          1
          down vote










          up vote
          1
          down vote









          Here is my solution for this string replacement task using only internal commands of cmd.exe with exception of FINDSTR.



          @echo off
          setlocal EnableExtensions DisableDelayedExpansion

          if not defined workingPlace set "workingPlace=%~dp0"
          set "TextFile=%workingPlace%bincsm.properties"
          if not exist "%TextFile%" goto EndBatch

          set "TempFile=%TEMP%csm.properties.tmp"
          set "FoundInfo="

          (for /F delims^=^ eol^= %%I in ('%SystemRoot%System32findstr.exe /N "^" "%TextFile%"') do (
          set "Line=%%I"
          setlocal EnableDelayedExpansion
          set "Line=!Line:*:=!"
          if not defined FoundInfo (
          if defined Line (
          if /I "!Line:~0,10!" == "CLASSPATH=" (
          if /I "!Line!" == "CLASSPATH=" (
          echo !Line!plugins/Numbering.jar
          endlocal
          set "FoundInfo=1"
          ) else if "!Line:plugins/Numbering.jar=!" == "!Line!" (
          set "Line=!Line:~0,10!plugins/Numbering.jar:!Line:~10!"
          echo !Line!
          endlocal
          set "FoundInfo=1"
          ) else (
          endlocal
          goto DeleteTempFile
          )
          ) else (
          echo(!Line!
          endlocal
          )
          ) else (
          echo/
          endlocal
          )
          ) else (
          echo(!Line!
          endlocal
          )
          ))>"%TempFile%"

          if not defined FoundInfo echo CLASSPATH=plugins/Numbering.jar>>"%TempFile%"
          move /Y "%TempFile%" "%TextFile%"

          :DeleteTempFile
          if exist "%TempFile%" del "%TempFile%"

          :EndBatch
          endlocal


          Read my answer on ow 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 line set "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 with CLASSSPATH= is processed by the inner code of FOR loop. Every line in file after the line starting with CLASSSPATH= is just output without further processing including empty lines.



          An empty line above line starting with CLASSSPATH= is also output with echo/ without any further processing.



          The first line starting case-insensitive with CLASSPATH= can be processed in three different ways:




          1. The line contains just CLASSPATH=.

            In this case the line is output as CLASSPATH=plugins/Numbering.jar and that's it.

          2. The line starts with CLASSPATH= and contains one or more characters, but not case-insensitive the string plugins/Numbering.jar.
            In this case the line is output within inserting plugins/Numbering.jar: after CLASSPATH=.

            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 of CLASSPATH=plugins/Numbering.jar:  with : and the trailing whitespaces at end.

          3. The line starts with CLASSPATH= and contains already case-insensitive the string plugins/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 line CLASSPATH=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 file csm.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 with CLASSPATH=.



          Note 2: The line with CLASSPATH= at top of file csm.properties reduces the process time.



          Summary of features of this solution:




          1. Does not modify the text file on containing already CLASSPATH= with plugins/Numbering.jar somewhere on line.

          2. Inserts plugins/Numbering.jar: after CLASSPATH= only if there are other class paths (or trailing whitespaces) on this line.

          3. Appends plugins/Numbering.jar to existing CLASSPATH= line not containing any other class path (and no trailing whitespaces on this line).

          4. Appends entire CLASSPATH= line with plugins/Numbering.jar to file not containing this line at all if the file exists at least.

          5. Keeps empty lines in text file and so modifies really only line with CLASSPATH= at beginning.

          6. Does not modify lines with VARIABLE==value (value with equal sign at beginning) to VARIABLE=value (equal sign at beginning removed).

          7. Does not modify spelling of CLASSPATH= and works for that reason also with classpath= or ClassPath= in file.

          8. Does not remove lines starting with ; 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 to set "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 and NEQ designed primary for integer comparisons should be in general not used for comparing two strings although this is possible. The usage of EQU and NEQ for string comparisons can in some cases with not double quoted strings result in an unexpected comparison result.






          share|improve this answer














          Here is my solution for this string replacement task using only internal commands of cmd.exe with exception of FINDSTR.



          @echo off
          setlocal EnableExtensions DisableDelayedExpansion

          if not defined workingPlace set "workingPlace=%~dp0"
          set "TextFile=%workingPlace%bincsm.properties"
          if not exist "%TextFile%" goto EndBatch

          set "TempFile=%TEMP%csm.properties.tmp"
          set "FoundInfo="

          (for /F delims^=^ eol^= %%I in ('%SystemRoot%System32findstr.exe /N "^" "%TextFile%"') do (
          set "Line=%%I"
          setlocal EnableDelayedExpansion
          set "Line=!Line:*:=!"
          if not defined FoundInfo (
          if defined Line (
          if /I "!Line:~0,10!" == "CLASSPATH=" (
          if /I "!Line!" == "CLASSPATH=" (
          echo !Line!plugins/Numbering.jar
          endlocal
          set "FoundInfo=1"
          ) else if "!Line:plugins/Numbering.jar=!" == "!Line!" (
          set "Line=!Line:~0,10!plugins/Numbering.jar:!Line:~10!"
          echo !Line!
          endlocal
          set "FoundInfo=1"
          ) else (
          endlocal
          goto DeleteTempFile
          )
          ) else (
          echo(!Line!
          endlocal
          )
          ) else (
          echo/
          endlocal
          )
          ) else (
          echo(!Line!
          endlocal
          )
          ))>"%TempFile%"

          if not defined FoundInfo echo CLASSPATH=plugins/Numbering.jar>>"%TempFile%"
          move /Y "%TempFile%" "%TextFile%"

          :DeleteTempFile
          if exist "%TempFile%" del "%TempFile%"

          :EndBatch
          endlocal


          Read my answer on ow 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 line set "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 with CLASSSPATH= is processed by the inner code of FOR loop. Every line in file after the line starting with CLASSSPATH= is just output without further processing including empty lines.



          An empty line above line starting with CLASSSPATH= is also output with echo/ without any further processing.



          The first line starting case-insensitive with CLASSPATH= can be processed in three different ways:




          1. The line contains just CLASSPATH=.

            In this case the line is output as CLASSPATH=plugins/Numbering.jar and that's it.

          2. The line starts with CLASSPATH= and contains one or more characters, but not case-insensitive the string plugins/Numbering.jar.
            In this case the line is output within inserting plugins/Numbering.jar: after CLASSPATH=.

            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 of CLASSPATH=plugins/Numbering.jar:  with : and the trailing whitespaces at end.

          3. The line starts with CLASSPATH= and contains already case-insensitive the string plugins/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 line CLASSPATH=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 file csm.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 with CLASSPATH=.



          Note 2: The line with CLASSPATH= at top of file csm.properties reduces the process time.



          Summary of features of this solution:




          1. Does not modify the text file on containing already CLASSPATH= with plugins/Numbering.jar somewhere on line.

          2. Inserts plugins/Numbering.jar: after CLASSPATH= only if there are other class paths (or trailing whitespaces) on this line.

          3. Appends plugins/Numbering.jar to existing CLASSPATH= line not containing any other class path (and no trailing whitespaces on this line).

          4. Appends entire CLASSPATH= line with plugins/Numbering.jar to file not containing this line at all if the file exists at least.

          5. Keeps empty lines in text file and so modifies really only line with CLASSPATH= at beginning.

          6. Does not modify lines with VARIABLE==value (value with equal sign at beginning) to VARIABLE=value (equal sign at beginning removed).

          7. Does not modify spelling of CLASSPATH= and works for that reason also with classpath= or ClassPath= in file.

          8. Does not remove lines starting with ; 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 to set "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 and NEQ designed primary for integer comparisons should be in general not used for comparing two strings although this is possible. The usage of EQU and NEQ for string comparisons can in some cases with not double quoted strings result in an unexpected comparison result.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 18 at 9:02

























          answered Nov 15 at 14:58









          Mofi

          27.3k83676




          27.3k83676






















              up vote
              0
              down vote













              @echo off
              setlocal disabledelayedexpansion

              set "search=CLASSPATH"
              set "insert=plugins/Numbering.jar:"

              set "textFile=%workingPlace%bincsm.properties"

              for /f "usebackq delims=" %%i in ("%textFile%") do (
              for /f "tokens=1* delims==" %%g in ("%%i") do (
              if /i "%%g" == "%search%" (
              set "token1=%%g"
              set "token2=%%h"
              setlocal enabledelayedexpansion
              >> "%textFile%.tmp" echo(!search!=!insert!!token2!
              endlocal
              ) else (
              set "line=%%i"
              setlocal enabledelayedexpansion
              >> "%textFile%.tmp" echo(!line!
              endlocal
              )
              )
              )

              move "%textFile%" "%textFile%.bak" && move "%textFile%.tmp" "%textFile%"


              Insert seems needed rather than a replace.



              The for loop reads each line of %textfile% and the nested for loop
              delimits on the = to store token 1 and token 2 with the remainder.



              If %search% is found, then !token1! and !token2! is set 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.






              share|improve this answer

























                up vote
                0
                down vote













                @echo off
                setlocal disabledelayedexpansion

                set "search=CLASSPATH"
                set "insert=plugins/Numbering.jar:"

                set "textFile=%workingPlace%bincsm.properties"

                for /f "usebackq delims=" %%i in ("%textFile%") do (
                for /f "tokens=1* delims==" %%g in ("%%i") do (
                if /i "%%g" == "%search%" (
                set "token1=%%g"
                set "token2=%%h"
                setlocal enabledelayedexpansion
                >> "%textFile%.tmp" echo(!search!=!insert!!token2!
                endlocal
                ) else (
                set "line=%%i"
                setlocal enabledelayedexpansion
                >> "%textFile%.tmp" echo(!line!
                endlocal
                )
                )
                )

                move "%textFile%" "%textFile%.bak" && move "%textFile%.tmp" "%textFile%"


                Insert seems needed rather than a replace.



                The for loop reads each line of %textfile% and the nested for loop
                delimits on the = to store token 1 and token 2 with the remainder.



                If %search% is found, then !token1! and !token2! is set 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.






                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  @echo off
                  setlocal disabledelayedexpansion

                  set "search=CLASSPATH"
                  set "insert=plugins/Numbering.jar:"

                  set "textFile=%workingPlace%bincsm.properties"

                  for /f "usebackq delims=" %%i in ("%textFile%") do (
                  for /f "tokens=1* delims==" %%g in ("%%i") do (
                  if /i "%%g" == "%search%" (
                  set "token1=%%g"
                  set "token2=%%h"
                  setlocal enabledelayedexpansion
                  >> "%textFile%.tmp" echo(!search!=!insert!!token2!
                  endlocal
                  ) else (
                  set "line=%%i"
                  setlocal enabledelayedexpansion
                  >> "%textFile%.tmp" echo(!line!
                  endlocal
                  )
                  )
                  )

                  move "%textFile%" "%textFile%.bak" && move "%textFile%.tmp" "%textFile%"


                  Insert seems needed rather than a replace.



                  The for loop reads each line of %textfile% and the nested for loop
                  delimits on the = to store token 1 and token 2 with the remainder.



                  If %search% is found, then !token1! and !token2! is set 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.






                  share|improve this answer












                  @echo off
                  setlocal disabledelayedexpansion

                  set "search=CLASSPATH"
                  set "insert=plugins/Numbering.jar:"

                  set "textFile=%workingPlace%bincsm.properties"

                  for /f "usebackq delims=" %%i in ("%textFile%") do (
                  for /f "tokens=1* delims==" %%g in ("%%i") do (
                  if /i "%%g" == "%search%" (
                  set "token1=%%g"
                  set "token2=%%h"
                  setlocal enabledelayedexpansion
                  >> "%textFile%.tmp" echo(!search!=!insert!!token2!
                  endlocal
                  ) else (
                  set "line=%%i"
                  setlocal enabledelayedexpansion
                  >> "%textFile%.tmp" echo(!line!
                  endlocal
                  )
                  )
                  )

                  move "%textFile%" "%textFile%.bak" && move "%textFile%.tmp" "%textFile%"


                  Insert seems needed rather than a replace.



                  The for loop reads each line of %textfile% and the nested for loop
                  delimits on the = to store token 1 and token 2 with the remainder.



                  If %search% is found, then !token1! and !token2! is set 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.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 15 at 15:45









                  michael_heath

                  2,6142616




                  2,6142616






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53319538%2fmodify-a-string-in-a-properties-file-with-batch%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                      ComboBox Display Member on multiple fields

                      Is it possible to collect Nectar points via Trainline?