Найти и заменить строку специальными символами, используя командный файл - PullRequest
0 голосов
/ 12 июня 2018

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

Проблема: нам приходится обновлять базу данных очень часто, и при этом файл изменяется.Я должен изменить один файл обратно, чтобы заставить вещи работать.Эта строка:

<network ipAdress="172.24.55.32" networkPort="9100" />

изменяется на эту строку:

<file filename="fffff" />

и должна быть заменена на первую строку с IP-адресом.

У меня естьпопытался использовать подпрограмму поиска и замены и может заставить ее работать в первой части, изменив «file filename» на «network ipAdress», но кавычки во втором разделе не позволяют скрипту работать правильно.Это код, который у меня есть.

@echo off
setlocal

call :FindReplace "file filename" "network ipAdress" BCPrint.XML
Timeout 2
call :FindReplace "fffff" "172.24.55.32" networkPort="9100" BCPrint.XML

exit /b

:FindReplace <findstr> <replstr> <file>
set tmp="%temp%\tmp.txt"
If not exist %temp%\_.vbs call :MakeReplace
for /f "tokens=*" %%a in ('dir "%3" /s /b /a-d /on') do (
  for /f "usebackq" %%b in (`Findstr /mic:"%~1" "%%a"`) do (
    echo(&Echo Replacing "%~1" with "%~2" in file %%~nxa
    <%%a cscript //nologo %temp%\_.vbs "%~1" "%~2">%tmp%
    if exist %tmp% move /Y %tmp% "%%~dpnxa">nul
  )
)
del %temp%\_.vbs
exit /b

:MakeReplace
>%temp%\_.vbs echo with Wscript
>>%temp%\_.vbs echo set args=.arguments
>>%temp%\_.vbs echo .StdOut.Write _
>>%temp%\_.vbs echo Replace(.StdIn.ReadAll,args(0),args(1),1,-1,1)
>>%temp%\_.vbs echo end with

Я также попытался установить вторую переменную как переменную, например:

set R2=172.24.55.32" networkPort="9100
call :FindReplace "file filename" "network ipAdress" BCPrint.XML
Timeout 2
call :FindReplace "fffff" "%R2%" BCPrint.XML

Также с escape-символами:

set ^R2=172.24.55.32" networkPort="9100^

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

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

Ответы [ 3 ]

0 голосов
/ 14 июня 2018

Загрузка JREPL.BAT , написанная Дейв Бенхам , представляющий собой пакетный файл / гибрид JScript для выполнения замены регулярного выражения в файле с использованием JScript и сохранения его в том же каталоге, что иПакетный файл ниже.

@echo off
call "%~dp0jrepl.bat" "file filename=\x22fffff" "network ipAdress=\x22172.24.55.32\x22 networkPort=\x229100" /XSEQ /F BCPrint.XML /O -

\x22 - это ", указанный в шестнадцатеричной форме, поскольку строка аргумента не может содержать символ двойной кавычки.

0 голосов
/ 11 августа 2018

Чтобы обновить строку в файле, который содержит «кавычки», будет работать следующее решение:

Создайте файл с именем replace_quot.ps1 в том же каталоге, что и ваш файл bat.Поместите следующие 2 строки в этот скрипт.

param([string]$Name_of_File)
(Get-Content $Name_of_File) -replace '&quot;', '"' | set-content $Name_of_File

В своем файле bat введите следующие строки

set File_Name=File Name.txt
set "Find_String=<file filename="fffff" />"
set "Replace_String=<network ipAdress="172.24.55.32" networkPort="9100" />"

set "Find_String=%Find_String:"=&quot;%"
set "Replace_String=%Replace_String:"=&quot;%"

powershell -command "(Get-Content '%File_Name%') -replace '[\x22]', '&quot;' | Set-Content '%File_Name%'"
powershell -command "(Get-Content '%File_Name%') -replace '%Find_String%', '%Replace_String%' | Set-Content '%File_Name%'"
Powershell.exe -executionpolicy remotesigned -File replace_quot.ps1 -Name_of_File "%File_Name%"

Обновите значение File_Name , чтобы оно соответствовало имени вашего файла.,Скрипт летучей мыши заменит кавычки их шестнадцатеричным значением как в строках, так и в файле.Затем он найдет строку, которую необходимо заменить, и восстановит ее до желаемого значения.Наконец, он вызовет скрипт replace_quot.ps1 , чтобы обновить шестнадцатеричные значения файла в кавычках до действительного символа кавычки.

0 голосов
/ 13 июня 2018

Передача аргументов, содержащих кавычки, очень трудна, поскольку есть несколько мест, где эти символы распознаются, поэтому вам приходилось каждый раз создавать отдельные escape-последовательности (^).

Следующий пример скриптатерпит неудачу при каждой попытке call:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define argument here:
set "_ARG=R2=172.24.55.32" networkPort="9100"

setlocal EnableDelayedExpansion
rem // Echo argument string to prove that variable is set:
echo(!_ARG!
echo/

rem // Call sub-routine with delayed expansion:
call :SUB "!_ARG!"
endlocal
rem // Call sub-routine with normal (immediate) expansion:
call :SUB "%_ARG%"
rem // Call sub-routine with double normal expansion (`call`):
call :SUB "%%_ARG%%"

endlocal
exit /B


:SUB
    setlocal DisableDelayedExpansion
    rem // Delayed expansion disabled during argument expansion:
    set "ARG=%~1"
    setlocal EnableDelayedExpansion
    rem // Delayed expansion enabled for argument display (`echo`):
    echo(!ARG!
    endlocal
    endlocal
    exit /B

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

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define argument here:
set "_ARG=R2=172.24.55.32" networkPort="9100"

setlocal EnableDelayedExpansion
rem // Echo argument string to prove that variable is set:
echo(!_ARG!
echo/
endlocal

rem // Call sub-routine and pass variable name:
call :SUB _ARG

endlocal
exit /B


:SUB
    setlocal EnableDelayedExpansion
    set "#ARG=%~1"
    rem /* Normal expansion is used to get the variable name;
    rem    delayed expansion is used to read its value: */
    echo(!%#ARG%!
    endlocal
    exit /B
...