Ste*_*son 5 batch-file find-replace
我写了一个批处理文件,我想用另一个.txt文件中的字符串覆盖键字符串.
目前它完全复制新的File.txt文件,但不会用OldFile.txt文件中的字符串替换字符串.
File.txt文件中的字符串示例:
...
#密码
PWORD =#AccountName
Account =#TownName
Town =#Postcode
Postcode =#LocationChangedDate
LocationChanged =
我想要替换的OldFile.txt文件中的字符串示例:
...
#密码
PWORD = ABC#AccountName
帐户= 123#TownName
Town = LDN#邮编
邮编= WS77TP#LocationChangedDate
LocationChanged = 01/01/2015
有人可以指出我正确的方向或解释我在哪里犯了错误?
@echo off
setlocal disableDelayedExpansion
::Variables
set InputFile=F:\EXCHANGE\3\Machine\File.txt
set OutputFile=F:\EXCHANGE\3\File-New.txt
set CopyFile=F:\EXCHANGE\3\OldMachine\OldFile.txt
set _strFindPword=Pword=.*
for /F "delims=" %%A in ('findstr /x "Pword=.*" %CopyFile%') do set _strInsertPword=%%A
echo.%_strInsertPword%
set _strFindAccount=Account=.*
for /F "delims=" %%B in ('findstr /x "Account=.*" %CopyFile%') do set _strInsertAccount=%%B
echo.%_strInsertAccount%
set _strFindTown=Town=.*
for /F "delims=" %%C in ('findstr /x "Town=.*" %CopyFile%') do set _strInsertTown=%%C
echo.%_strInsertTown%
set _strFindLocationChanged=LocationChanged=.*
for /F "delims=" %%D in ('findstr /x "LocationChanged=.*" %CopyFile%') do set _strInsertLocationChanged=%%D
echo.%_strInsertLocationChanged%
set _strFindPostcode=Postcode=.*
for /F "delims=" %%E in ('findstr /x "Postcode=.*" %CopyFile%') do set _strInsertPostcode=%%E
echo.%_strInsertPostcode%
(
for /F "delims=" %%L in ('findstr /n "^" "%InputFile%"') do (
set "line=%%L"
setlocal EnableDelayedExpansion
set "line=!line:*:=!"
if "%%L" equ "_strFindPword" (echo.!_strInsertPword!) else (
if "%%L" equ "%_strFindAccount%" (echo.!_strInsertAccount!) else (
if "%%L" equ "%_strFindTown%" (echo.!_strInsertTown!) else (
if "%%L" equ "%_strFindLocationChanged%" (echo.!_strInsertLocationChanged!) else (
if "%%L" equ "%_strFindPostcode%" (echo.!_strInsertPostcode!) else (echo.!line!)
)
)
)
)
endlocal
)
) > "%OutputFile%"
del %InputFile%
ren %OutputFile% File.txt
pause
Run Code Online (Sandbox Code Playgroud)
我想我终于明白了...
它能做什么:
_PWD值为 的标记(变量)Pword=,它将创建一个_PWDCONTENTS内容为Pword=ABC)。CONTENTS变量将转储到OutFile.txt中,否则转储到原始行中。因为这种情况发生在内部for循环中,所以我必须添加一些额外的逻辑(_WROTEvar)以避免多次写入相同的行。注意事项:
它应该(嗯,除了做它应该做的事情之外)是“可配置的”(代码很复杂,如果你愿意的话,它正在走向元:)),这意味着如果标记之间有变化,代码不应该改变(嗯,会有代码更改,但不是在功能部分,仅在变量定义中)。让我详细说明一下:
Town=字符串,那么您所要做的就是_TOWN从_ALL:中删除set _ALL=_PWD _ACCT _POST _LOC。set _NAME=Name=并将其添加到_ALL: set _ALL=_PWD _ACCT _TOWN _POST _LOC _NAME。作为间接后果,我没有关注性能,因此它可能运行缓慢。无论如何,我试图将磁盘访问(速度非常慢)保持在最低限度(一个例子是当有 2 个for循环迭代文件内容时 - 假设每次迭代都需要一次磁盘访问;这可能不是真的,并且Win有 IO 缓冲 - 这是外部缓冲)。
rem开头的 即可。这是批处理代码:
@echo off
setlocal enabledelayedexpansion
set _INFILE="File.txt"
set _OUTFILE="NewFile.txt"
set _OLDFILE="OldFile.txt"
set _PWD=Pword=
set _ACCT=Account=
set _TOWN=Town=
set _POST=Postcode=
set _LOC=LocationChanged=
set _ALL=_PWD _ACCT _TOWN _POST _LOC
echo Parsing old file contents...
for /f "tokens=*" %%f in ('type !_OLDFILE!') do (
for %%g in (!_ALL!) do (
echo %%f | findstr /b /c:!%%g! 1>nul
if "!errorlevel!" equ "0" (
set %%gCONTENTS=%%f
)
)
)
copy nul %_OUTFILE%
echo Merging the old file contents into the new file...
set _WROTE=0
for /f "tokens=*" %%f in ('findstr /n "^^" !_INFILE!') do (
set _TMPVAR0=%%f
set _TMPVAR0=!_TMPVAR0:*:=!
for %%g in (!_ALL!) do (
echo !_TMPVAR0! | findstr /b /c:!%%g! 1>nul
if "!errorlevel!" equ "0" (
echo.!%%gCONTENTS!>>!_OUTFILE!
set _WROTE=1
)
)
if "!_WROTE!" equ "0" (
echo.!_TMPVAR0!>>!_OUTFILE!
) else (
set _WROTE=0
)
)
rem copy /-y %_OUTFILE% %_INFILE%
Run Code Online (Sandbox Code Playgroud)
@EDIT0:使用@StevoStephenson建议(作为问题片段的一部分),我将(第二个)外部for循环替换为('findstr /n "^^" !_INFILE!')以包含空行,因此第三个注释不再适用(删除)。还做了一些小更改以允许文件在其路径中包含SPACE。