查找和使用if语句和变量将for/f替换为字符串 [英] Find & Replace string using for /f with if statement and variables

查看:85
本文介绍了查找和使用if语句和变量将for/f替换为字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写了一个批处理文件,我想用另一个.txt文件中的字符串覆盖键字符串.

I have written a batch file which I want to overwrite key strings with strings from another .txt file.

当前,它可以完美地复制新的File.txt文件,但不会将其替换为OldFile.txt文件中的字符串.

currently it copies the new File.txt file perfectly but does not replace the strings with the strings from OldFile.txt file.

File.txt文件中的字符串示例:

example of strings in File.txt file:

...

#密码
Pword =

# Password
Pword=

#AccountName
帐户=

# AccountName
Account=

#TownName
镇=

# TownName
Town=

#邮政编码
邮政编码=

# Postcode
Postcode=

#LocationChangedDate
LocationChanged =

# LocationChangedDate
LocationChanged=

我要替换的OldFile.txt文件中字符串的示例:

example of strings in OldFile.txt file I want to replace from:

...

#密码
Pword = ABC

# Password
Pword=ABC

#AccountName
帐户= 123

# AccountName
Account=123

#TownName
镇= LDN

# TownName
Town=LDN

#邮政编码
邮政编码= WS77TP

# Postcode
Postcode=WS77TP

#LocationChangedDate
LocationChanged = 01/01/2015

# LocationChangedDate
LocationChanged=01/01/2015

有人可以向我指出正确的方向或解释我犯错的地方吗?

Can someone please point me in the right direction or explain where I have made a mistake?

@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

推荐答案

我想我终于明白了...

I think I finally got it...

它的作用:

  • 遍历 OldFile.txt 内容,搜索标记,如果发现标记,则将其存储到要在嵌套步骤中使用的环境变量中(例如,用于_PWD标记(变量),该标记具有值Pword=,它将创建一个_PWDCONTENTS变量,其内容为Pword=ABC).
  • 它遍历 File.txt 内容,搜索相同的标记,如果找到一个标记,则将相应的CONTENTS变量转储到 OutFile.txt 中,否则原来的线.因为这是在内部for循环中发生的,所以我不得不添加一些额外的逻辑(_WROTE var),以避免多次写同一行.
  • It goes through the OldFile.txt content, searching for markers, if found they are stored into environment variables to be used in the nest step (e.g. for _PWD marker (variable) which has a value of Pword=, it will create a _PWDCONTENTS variable with the content of Pword=ABC).
  • It goes through File.txt content, searching for the same markers, if one marker found, the corresponding CONTENTS variable is dumped in the OutFile.txt, else the original line. Because that happens in the inner for loop, I had to add some extra logic (the _WROTE var) to avoid writing the same lines more than once.

注释:

  • (除了做应该做的事情之外)应该是可配置的"(代码很复杂,如果可以的话,它正朝着 meta 前进),这意味着如果标记之间有更改,则代码不应更改(当然,代码也应更改,但在功能部分中,仅在变量定义中不能更改).让我详细说明:

  • It is supposed (well, besides doing what it's supposed to) to be "configurable" (the code is complicated, it's heading towards meta :) if you will), meaning that if there are changes between the markers the code shouldn't change (well there would be code changes, but not in the functional part only in variable definitions). Let me detail:

  • 如果您不再需要替换Town=字符串,那么您要做的就是从_ALL:set _ALL=_PWD _ACCT _POST _LOC中删除_TOWN.
  • 相反:如果要添加其他标签(我们将其称为 Name ),则必须创建一个新的环境变量:set _NAME=Name=并将其添加到_ALL:.
  • If you no longer need to replace the Town= string, then all you have to do is removing _TOWN from _ALL: set _ALL=_PWD _ACCT _POST _LOC.
  • The reverse: if you want to add some other tag (let's call it Name), you have to create a new environment variable: set _NAME=Name= and add it to _ALL: set _ALL=_PWD _ACCT _TOWN _POST _LOC _NAME.

作为间接的结果,我没有关注性能,因此它可能运行缓慢.无论如何,我试图将磁盘访问(非常缓慢的速度)保持在最低限度(一个例子是,当有2个for循环时,一个对文件内容进行迭代的循环-假设每次迭代都需要磁盘访问;这可能不是)是的, Win 具有IO缓冲-这是外部缓冲).

As an indirect consequence, I didn't focus on performance, so it might run slow. Anyway I tried to keep the disk accesses (which are painfully slow) to a minimum (one example is when having 2 for loops the one that iterates on a file contents - assuming that each iteration takes a disk access; this might not be true, and Win has IO buffering - it's the outer one).

这是批处理代码:

@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%

@ EDIT0 :使用@StevoStephenson建议(作为问题片段的一部分),我将第2个外部for循环替换为('findstr /n "^^" !_INFILE!'),以便包含空行,因此第三句话不再适用(删除).还进行了一些小的更改,以允许路径中包含 SPACE 的文件.

@EDIT0: Using @StevoStephenson suggestion (as part of the question snippet), I replaced the (2nd) outer for loop to ('findstr /n "^^" !_INFILE!') in order to include the empty lines, so the 3rd remark no longer applies (deleting). Also did some small changes to allow files that contain SPACE s in their paths.

这篇关于查找和使用if语句和变量将for/f替换为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆