Как найти и заменить строку с подстановочным знаком в командном файле? - PullRequest
0 голосов
/ 25 июня 2019

Я новичок во всем этом, так что успокойся.Я пытаюсь автоматизировать процесс, в котором я меняю порт для конкретной службы.Порт определяется в файле streamstack.exe.config.У меня есть кое-что, что найдет и заменит определенную строку в файле, однако в некоторых ситуациях я не буду знать определенный номер порта.Можно ли найти строку, содержащую подстановочный знак, и заменить ее предопределенной строкой?Например, найдите "localhost:.*" и замените на "localhost:80"?

Я смог использовать findstr с wildcard, однако я не смог использовать какую-то замену с выводом,Я также нашел что-то, что найдет замену, используя setlocal enabledelayedexpansion, однако я не могу понять, как использовать с ним подстановочный знак.

Мой код:

@echo off

set "replace=localhost:.*"
set "replaced=localhost:80"

set "source=c:\blah\blah\streamstack.exe.config"
set "target=c:\blah\blah\streamstack1.exe.config"


setlocal enableDelayedExpansion
(
   for /f "tokens=1* delims=:" %%a in ('findstr /N "^" %source%') do (
      set "line=%%b"
      if defined line set "line=!line:%replace%=%replaced%!"
      echo(!line!
   )
) > %target%
endlocal

Я надеялсяон найдет строку, содержащую localhost:, за которой следует любая группа чисел, представляющих порт, и заменит ее на localhost:80, то есть порт, который мне нужен для службы.

Ответы [ 3 ]

0 голосов
/ 25 июня 2019

Вы не предоставили никаких сведений о формате файла конфигурации.

Если для каждой строки задано одно значение имени / значения, а порядок строк не имеет значения , а не , то существует очень простое пакетное решение, которое также очень эффективно. Используйте FINDSTR для записи всех строк кроме строки localhost, а затем добавьте желаемую строку localhost.

>"%target%" (findstr /v "^http://localhost:" "%source%" & echo http://localhost:80)

Конечно, вышеописанное не сработает, если важен порядок строк.

Вы должны проверить мою утилиту поиска / замены регулярного выражения JREPL.BAT . Это очень мощный, но простой в использовании. Это чистый скрипт (гибридный пакет / JScript), который запускается на любом компьютере с Windows начиная с XP.

Используя тот же поиск / замену, который вы использовали в PowerShell, решение JREPL будет

call jrepl "(http://localhost):.*" "$1:80" /f "%source%" /o "%target%"

Я использовал группу захвата регулярных выражений, чтобы немного набрать текст.

JREPL имеет множество опций, и полная утилита встроена в утилиту. Используйте jrepl /?help, чтобы получить описание всех доступных типов помощи.

0 голосов
/ 25 июня 2019

Поскольку вы пытаетесь заменить номер порта в URL-адресе, я немного расширил строку поиска, чтобы включить ведущий :// после определения протокола http или https и перед именем хоста, а такжезавершающий / после номера порта (это также соответствует ваш собственный ответ ).

Следующий скрипт заменяет номер порта только в первом появлении желаемого URL, который найденкогда встречается строка типа :// плюс заданное имя хоста плюс : плюс чисто числовой номер порта плюс /:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_SOURCE=c:\blah\blah\streamstack.exe.config" & rem // (original file)
set "_TARGET=c:\blah\blah\streamstack.exe.config" & rem // (modified file)
set "_TEMP=%TEMP%\%~n0_%RANDOM%.tmp"              & rem // (temporary file)
set "_HOST=localhost"                             & rem // (host name)
set "_PORT=80"                                    & rem // (new port name)

rem // Define to write to console if no target file is given:
if not defined _TARGET set "_TEMP=con"

rem // Store line-feed in variable:
(set ^"_LF=^
%= blank line =%
^")

rem // Write output to temporary file:
> "%_TEMP%" (
    rem // Read source file line by line, precede each line by line number plus `:`:
    for /F "delims=" %%L in ('findstr /N "^" "%_SOURCE%"') do (
        rem // Store currently iterated line, reset buffer for part left to host name:
        set "LINE=%%L" & set "LEFT="
        rem // Toggle delayed expansion to avoid trouble with exclamation marks:
        setlocal EnableDelayedExpansion
        rem // Get line portion right to `://` + host name + `:`:
        set "RIGHT=!LINE:*://%_HOST%:=!"
        rem // Check whether host name part has really been found:
        if not "!LINE!" == "!RIGHT!" (
            rem /* Buffer right line portion in a `for` variable
            rem    to transport it over the `endlocal` barrier: */
            for /F "delims=" %%J in (^""!RIGHT!"^") do (
                rem // Replace `://` + host name + `:` by a line-feed:
                for /F "delims=" %%I in (^"!LINE:://%_HOST%:^=^%_LF%%_LF%!^") do (
                    rem /* Ensure to only process first line of multi-line string
                    rem    to get the line portion left to `://`+ host name + `:`: */
                    if not defined LEFT (
                        endlocal
                        rem /* Store line portion left to `://` + host name + `:`,
                        rem    restore right line portion from `for` variable: */
                        set "LEFT=%%I" & set "RIGHT=%%~J"
                        rem /* Split off everything behind the first `/`, which
                        rem    constitutes the port number: */
                        for /F "delims=/" %%F in ("0%%~J") do (
                            rem /* Check whether port number is purely numeric;
                            rem    this is done by checking whether a `for /F` loop
                            rem    iterates if numerals are defined as delimiters: */
                            for /F "delims=0123456789" %%E in ("%%F") do rem/
                        ) && (
                            rem // `for /F` loop iterated, hence keep current line:
                            setlocal EnableDelayedExpansion
                        ) || (
                            rem // `for /F` loop did not iterate, change port number:
                            setlocal EnableDelayedExpansion
                            set "LINE=!LEFT!://%_HOST%:%_PORT%/!RIGHT:*/=!"
                        )
                    )
                )
            )
        )
        rem // Return line string:
        echo(!LINE:*:=!
        endlocal
    )
)
rem /* Move temporary file onto target file;
rem    this allows source and target files to be identical: */
if defined _TARGET > nul move /Y "%_TEMP%" "%_TARGET%"

endlocal
exit /B
0 голосов
/ 25 июня 2019

Я решил пойти другим путем и вызвать PowerShell вместо того, чтобы пытаться сделать все это в файле bat.

(Get-Content C:\Users\David\Desktop\streamstack.exe.config) | ForEach-Object { $_ - 
replace "http://localhost:.*/", "http://localhost:80/" } | Set-Content 
c:\blah\blah\streamstack.exe.config

Это похоже на работу, и я могу выполнить ее изнутри, используя ...

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