Изменить строку в файле .properties с помощью пакета - PullRequest
0 голосов
/ 15 ноября 2018

Я пытаюсь изменить определенное свойство в моем csm.properties, выполнив скрипт.Я много искал и в итоге пришел к этому коду.

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
        )
    )
)

Этот код должен читать каждую строку в моем файле и использовать = в качестве разделителя.Если код получает "CLASSPATH" как свойство, эта строка должна быть изменена.Но похоже, что CLASSPATH не найден.

Вот так выглядит csm.properties:

#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

После изменений CLASSPATH должен выглядеть следующим образом:

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

Ответы [ 4 ]

0 голосов
/ 15 ноября 2018
@echo off
setlocal disabledelayedexpansion

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

set "textFile=%workingPlace%bin\csm.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%"

Вставка кажется необходимой, а не заменой.

Цикл for считывает каждую строку %textfile%, а вложенный цикл for разграничивает = для хранения токена 1 и токена 2с остатком.

Если найдено %search%, то !token1! и !token2! равны set значениям токена.set обычно может обрабатывать отравляющие символы после него, так почему он используется.Расширение задерживается, поэтому ядовитые символы выводятся в файл без раскрытия в источник.

Если %search% не найдено, строка устанавливается на !line!, расширение задерживается, а затем строка выводитсяв файл.

Примечание: %workingPlace% неизвестно, поэтому при необходимости исправьте путь.

0 голосов
/ 15 ноября 2018

Simpler ...

@echo OFF
setlocal

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

set "textFile=%workingPlace%bin\csm.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%"
0 голосов
/ 15 ноября 2018

Вот мое решение для этой задачи замены строки, используя только внутренние команды cmd.exe, за исключением FINDSTR .

@echo off
setlocal EnableExtensions DisableDelayedExpansion

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

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

(for /F delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.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

Прочитать мой ответ на Как читатьи печатать содержимое текстового файла построчно? почему команда FINDSTR используется только для вывода каждой строки в файле csm.properties, включая пустые строки, игнорируемые FOR по умолчанию со строкойномер и :, чтобы любая строка не игнорировалась FOR .Номер строки и двоеточие удаляются командной строкой set "Line=!Line:*:=!".

В верхней части пакетного файла есть переменная окружения FoundInfo undefined, которая устанавливается после того, как строка начинается без учета регистра с CLASSSPATH= обрабатывается внутренним кодом цикла FOR .Каждая строка в файле после строки, начинающейся с CLASSSPATH=, выводится без дальнейшей обработки, включая пустые строки.

Пустая строка над строкой, начинающейся с CLASSSPATH=, также выводится с echo/ без дальнейшей обработки.

Первая строка, начинающаяся без учета регистра с CLASSPATH=, может обрабатываться тремя различными способами:

  1. В строке содержится только CLASSPATH=.
    В этом случае строкавыводится как CLASSPATH=plugins/Numbering.jar и все.
  2. Строка начинается с CLASSPATH= и содержит один или несколько символов, но без учета регистра строки plugins/Numbering.jar.В этом случае строка выводится при вставке plugins/Numbering.jar\: после CLASSPATH=.
    Обратите внимание, что строка с CLASSPATH= и одним или несколькими конечными пробелами / табуляциями также приведет к переходу во вторую ветвь, что приведет, например, квывод CLASSPATH=plugins/Numbering.jar\: с \: и завершающими пробелами в конце.
  3. Строка начинается с CLASSPATH= и содержит уже без учета регистра строку plugins/Numbering.jar где-то в строке.
    В этомв случае, если цикл FOR немедленно завершается с переходом к метке DeleteTempFile без обработки какой-либо дополнительной строки из захваченного вывода FINDSTR .Таким образом, дата последнего изменения файла не изменяется из-за того, что ничего не изменилось в содержимом файла.(Мне не нравится изменение даты последнего изменения содержимого файла, которое на самом деле не было изменено.)

После того, как цикл FOR проверен на наличие какой-либо строки, начинающейся без учета регистра сCLASSPATH= вообще в файле.Строка CLASSPATH=plugins/Numbering.jar добавляется к временному файлу, если это не так.

Наконец, если временный файл определенно отличается от csm.properties, временный файл перемещается поверх существующего файла csm.properties, если это так.возможно вообще, и последний временный файл удаляется, если он все еще существует.

Примечание 1: Решение может быть проще без использования FINDSTR , если файл csm.properties не содержит пустых строк или допускается удаление пустых строк при обновлении строки с CLASSPATH=.

Примечание 2: Строка с CLASSPATH= вверху файла csm.properties сокращает время обработки.

Краткое описание возможностей этого решения:

  1. Не изменяет текстовый файл, содержащий уже CLASSPATH=, где plugins/Numbering.jar где-то в строке.
  2. Вставляет plugins/Numbering.jar\: после CLASSPATH=, только если в этой строке есть другие пути классов (или конечные пробелы).
  3. Добавляет plugins/Numbering.jar к существующей строке CLASSPATH=, не содержащей какого-либо другого классапуть (и нет следавводя пробелы в этой строке).
  4. Добавляет всю строку CLASSPATH= с plugins/Numbering.jar к файлу, не содержащему эту строку вообще, если файл существует хотя бы.
  5. Сохраняет пустые строки в текстовом файлеи поэтому действительно изменяет только строку с CLASSPATH= в начале.
  6. Не изменяет строки с VARIABLE==value (значение со знаком равенства в начале) до VARIABLE=value (знак равенства в начале удален).
  7. Не изменяет орфографию CLASSPATH= и работает по этой причине также с classpath= или ClassPath= в файле.
  8. Не удаляет строки, начинающиеся с ; по умолчанию FORОпция конца строки (eol).

Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните там следующие команды и внимательно прочитайте все страницы справки, отображаемые для каждой команды.

  • del /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • move /?
  • set /?
  • setlocal /?

См. Также Почему не выводится строкас 'echo% var%' после использования 'set var = text' в командной строке? и Как установить переменные окружения с пробелами? Эти ответы объясняют, почему в большинстве случаев set variable="value" не подходити в чем отличие от set "variable=value", который является предпочтительным синтаксисом для определения переменной среды со строковым значением.

См. также Символ, эквивалентный NEQ, LSS, GTR и т. д. в пакете Windowsфайлы , объясняющие, как работает сравнение строк с командой IF и почему операторы EQU и NEQ разработали primary для целочисленных сравнений вообще не следует использовать для сравнения двух строк, хотя это возможно.Использование EQU и NEQ для сравнения строк в некоторых случаях может привести к неожиданному результату сравнения строк без двойных кавычек.

0 голосов
/ 15 ноября 2018

Вы можете попробовать:

@echo off
setlocal enableextensions disabledelayedexpansion

 set "replace=plugins^/Numbering.jar^\^:"
 set "textFile=%workingPlace%bin\csm.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
     )
  )
)

Аналогичная теория, полная строка будет заменена только в том случае, если первый токен (%% i) соответствует CLASSMAP

Пожалуйста, не меняйте двойные кавычки в командах set.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...