我需要用纯批处理的文本文件中的用户输入替换HOST =
之后的文本。
名称VM-TEST
并不总是相同的,并且可以更改,因为它将在多个文件中使用。
我被困在这里。
文字示例:
(ADDRESS = (PROTOCOL = TCP)(HOST = VM-TEST)(PORT = 1521))
我只有这个:
@echo off &setlocal
set "search=host ="
set "replace=HOST = test"
set "textfile=Input.txt"
set "newfile=Output.txt"
(for /f "delims=" %%i in (%textfile%) do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
echo(!line!
endlocal
))>"%newfile%"
del %textfile%
rename %newfile% %textfile%
答案 0 :(得分:0)
嘿:)我建立了一个小脚本,可以完成这项工作。 它将首先在左括号中分割属性,因此您可以检查其是否与要查找的属性匹配。这是使用findstr / r完成的,因此可以将简单的正则表达式编写为搜索字符串。您的名称“ VM-TEST”在正则表达式中表示为“。*”,因此可以是任何字符串。
@echo off & setlocal
set "search=host = .*)"
set "replace=HOST = test)"
set "textfile=in.txt"
set "newfile=out.txt"
del "%newfile%" 2>nul
for /f "usebackq delims=" %%L in ("%textfile%") do (
call :replaceProperty "%%~L"
)
del "%textfile%"
rename "%newfile%" "%textfile%"
exit
:replaceProperty
set "_remainingLine=%~1"
set "_outputLine="
:replaceProperty_while
if "%_remainingLine%"=="" goto break
if "%_remainingLine:~0,1%"=="(" (
rem this needs to be checked additionally as for /f skips empty tokens
set "_outputLine=%_outputLine%("
set "_remainingLine=%_remainingLine:~1%"
goto replaceProperty_while
)
for /F "tokens=1* delims=(" %%q in ("%_remainingLine%") do (
echo:%%q|findstr /i /r /c:"^%search%$">nul
if errorlevel 1 (
set "_outputLine=%_outputLine%%%q"
) else (
set "_outputLine=%_outputLine%%replace%"
)
if "%%r"=="" (
goto break
) else (
set "_remainingLine=(%%r"
)
)
goto replaceProperty_while
:break
rem Finished processing the line. Write output and exit subroutine.
rem This can't be done in the if-block because the output line will contain brackets.
echo:%_outputLine%>>"%newfile%"
exit /b
这是我用于测试的示例文件:
(ADDRESS = (PROTOCOL = TCP)(HOST = VM-TEST)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = Something_else)(PORT = 1521))
this line won't get modified
(this works as well but
trailing brackets will get lost though (
((some other stuff = (text) ))
((HOST = VM-TEST)(PORT = 1521)(PROTOCOL = TCP))
编辑#1,2:更新了代码,以提供领先的空白支持和性能改进。
编辑#3:我假设文件中的每一行至少包含一个空格,但是如果您希望不丢失空行,则可以用以下内容替换第一个for /f "usebackq ...
循环:< / p>
for /f "tokens=1* delims=:" %%K in ('findstr /n /r "^" "%textfile%"') do (
call :replaceProperty "%%~L"
)
答案 1 :(得分:0)
您可以尝试以下脚本:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_ROOT=D:\Target" & rem // (path to target directory)
set "_IFILE=Input.txt" & rem // (name of input file)
set "_OFILE=Output.txt" & rem // (name of output file)
set "_SEARCH=HOST" & rem // (keyword to search for)
set /P _REPLAC="Enter new HOST value: " & rem // (replacement value)
rem // Gather horizontal tabulator (TAB) character:
for /F "delims=" %%T in ('forfiles /P "%~dp0." /M "%~nx0" /C "cmd /C echo/0x09"') do set "_TAB=%%T"
rem // Write to output file:
> "%_ROOT%\%_OFILE%" (
rem /* Read from input file line by line, precede each line with line number + `:`
rem in order not to appear empty to `for /F` and therefore not to be skipped: */
for /F "delims=" %%L in ('findstr /N "^" "%_ROOT%\%_IFILE%"') do (
rem // Store current line, reset line buffer:
set "LINE=%%L" & set "COLL=("
rem // Toggle delayed expansion to avoid trouble with `!`:
setlocal EnableDelayedExpansion
rem // Remove temporary line number + `:` prefix:
set "LINE=!LINE:*:=!"
rem // Skip processing of an empty line:
if defined LINE (
rem // Skip processing of a line that contains `*`, `?`, `<`, `>`:
if "!LINE!"=="!LINE:**=!" if "!LINE!"=="!LINE:*?=!" if "!LINE!"=="!LINE:*<=!" if "!LINE!"=="!LINE:*>=!" (
rem // Temporarily double `"`:
set "LINE=!LINE:"=""!^"
rem // Split line at every `(` and loop through the items:
for %%I in ("!LINE:(=" "!") do (
endlocal
rem // Store current item:
set "ITEM=%%~I"
rem // Split item into keyword and remainder:
for /F "tokens=1* delims==%_TAB% " %%G in ("%%~I") do (
rem // Check whether keyword matches:
if /I "%%G"=="%_SEARCH%" (
rem // Split off `)` and everything behind from remainder:
set "REST=%%H"
setlocal EnableDelayedExpansion
for /F "tokens=1* delims=)" %%E in ("!REST:)=)(!") do (
endlocal
rem // Rebuild new item with replacement value:
set "ITEM=%%G = %_REPLAC%)%%F"
setlocal EnableDelayedExpansion
)
endlocal
)
)
setlocal EnableDelayedExpansion
rem // Revert doubling `"`:
if defined ITEM set "ITEM=!ITEM:""="!^"
rem /* Append item to line buffer;
rem transport result beyond `endlocal`: */
if defined ITEM set "ITEM=!ITEM:(=!"
for /F "delims=" %%K in ("!COLL!(!ITEM!") do (
endlocal
set "COLL=%%K"
setlocal EnableDelayedExpansion
)
)
set "LINE=!COLL:~2!"
)
)
rem // Return resulting line:
echo(!LINE!
endlocal
)
)
endlocal
exit /B
以下限制适用:
=
, SPACE , TAB ,(
,)
; HOST
)()(要进行更改,请从/I
中删除if /I "%%G"=="%_SEARCH%"
选项); HOST
)不得包含任何字符*
,?
,<
,>
;如果这样做,则无法执行所需的替换; =
)中,HOST = VM-TEST
-符号周围的空格的原始顺序未得到维护,它始终是关键字+ SPACE + =
+ 空格 +替换值;