批量替换参数中的值

时间:2016-04-28 14:25:44

标签: windows batch-file

我正在尝试创建一个用于修改xml文件的脚本。 在这个xml文件中,我有一些像这样的行:

<tag parameter="value" versionNumber="2.0.3" anotherParameter="value">

我希望用新的值替换versionNumber的值。

我对通过不同的路线没有任何问题,但我正在努力改变价值。 有任何想法吗? 我不会使用任何其他脚本或工具,只需批处理。

提前致谢

3 个答案:

答案 0 :(得分:2)

这是一个纯解决方案(我们称之为change-version.bat):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem Define constants here:
set "XML_FILE=.\sample.xml"
set "TAG_NAME=tag"
set "PAR_NAME=versionNumber"
set "PAR_NEW_VAL="3.2.1""

for /F usebackq^ delims^=^ eol^= %%L in ("%XML_FILE%") do (
    set "LINE=%%L"
    for /F "tokens=1,* delims=< eol=<" %%D in ("%%L") do (
        set "PRE=%%D" & set "LIN=%%E"
        if not defined LIN (set "PRE=" & set "LIN=%%D")
        setlocal EnableDelayedExpansion
        for /F "tokens=1,* eol= " %%F in ("!LIN!") do (
            setlocal DisableDelayedExpansion
            set "INT=%%F" & set "TAG=%%G"
            setlocal EnableDelayedExpansion
            if /I "!INT!"=="%TAG_NAME%" (
                for /F "tokens=1,* delims=> eol=>" %%T in ("!TAG!") do (
                    setlocal DisableDelayedExpansion
                    set "TAG=%%T" & set "END=%%U"
                    call :SUB NEW TAG
                    setlocal EnableDelayedExpansion
                    echo(!PRE!^<%TAG_NAME%!NEW!^>!END!
                    endlocal
                    endlocal
                )
            ) else (
                echo(!LINE!
            )
            endlocal
            endlocal
        )
        endlocal
    )
)

endlocal
exit /B


:SUB var_new var_tag
set "%~1="
:LOOP
setlocal EnableDelayedExpansion
for /F "tokens=1,* eol= " %%P in ("!%~2!") do (
    endlocal
    for /F "tokens=1,* delims== eol==" %%V in ("%%P") do (
        if /I "%%V"=="%PAR_NAME%" (
            set "PAR=%%V=%PAR_NEW_VAL%"
        ) else (
            set "PAR=%%V=%%W"
        )
    )
    set "%~2=%%Q"
    setlocal EnableDelayedExpansion
)
for /F delims^=^ eol^= %%S in ("!%~1! !PAR!") do (
    endlocal & set "%~1=%%S"
)
if defined %~2 goto :LOOP
exit /B

为此,必须满足以下XML数据条件:

  • 包含标记<tag>的行不包含任何其他XML标记;
  • 包含参数<tag>的标记versionNumber不得跨越多行;
  • 参数定义不得在=符号周围包含空格;
  • (引用的)参数值不得包含<>个字符;
  • 标签和参数名称都不区分大小写;

脚本解析当前目录中的XML文件sample.xml 要将结果写入文件而不是控制台,请将其重定向为:

"change-version.bat" > "result.xml"

答案 1 :(得分:1)

使用板载的东西并不容易。查看Is there any sed like utility for cmd.exe

基本上,您将创建一个执行替换的短脚本(sed.vbs):

Dim pat, pa tparts, rxp, inp
pat = WScript.Arguments(0)
patparts = Split(pat,"/")
Set rxp = new RegExp
rxp.Global = True
rxp.Multiline = False
rxp.Pattern = patparts(1)
Do While Not WScript.StdIn.AtEndOfStream
    inp = WScript.StdIn.ReadLine()
    WScript.Echo rxp.Replace(inp, patparts(2))
Loop

最后执行命令以从Windows Batch替换:

csript //NoLogo sed.vbs s/2.0.3/2.0.4/ < yourFile.xml > newFile.xml

答案 2 :(得分:0)

有几种不同的方法可以解决这个问题,但最有效的方法是通过VBScript / JScript编程语言的regexp替换功能,最简单的方法是使用Batch-JScript混合脚本:

SELECT OBJECT_NAME(OBJECT_ID) AS DatabaseName, last_user_update,*
FROM sys.dm_db_index_usage_stats
WHERE OBJECT_ID=OBJECT_ID('TestTableName') 

使用.BAT扩展名保存此文件。