5

在挣扎了 2 天之后,我仍然无法找到解决 Windows 批处理脚本问题的方法。

我想要做的是逐行读取html文件,如果在特定行中找到匹配的关键字,则将该行替换为某些内容(html标签和变量组合)

无论我做什么,每当我尝试将 html 标签推送到文件时,我总是会收到一些错误“此时应该是 < ”。看起来批处理脚本不喜欢 html。

这是我的代码:

脚本.bat

for /F "tokens=1,2,3,4,5,6,7" %%i in (output.txt) do call :process %%i %%j %%k %%l %%m %%n %%o
goto :sendreport

:: procedure to prepare report

:process
    SETLOCAL EnableDelayedExpansion

    set UBENAME=%1
    set UBEVER=%2
    set UBESTAT=%3
    set RUNDATE=%4
    set STARTTIME=%5
    set ENDTIME=%6
    set TOTALTIME=%7

    SET FINDWHAT=%UBENAME%%UBEVER%  :: letter to find in the file
    SET REPLACEWITH=^<tr^>^<td^> %UBENAME% ^</td^>^<td^> %UBEVER% ^</td^>^<td^> %UBESTAT% ^</td^>^<td^> %RUNDATE% ^</td^>^<td^> %STARTTIME% ^</td^>^<td^> %ENDTIME% ^</td^>^<td^> %TOTALTIME% ^</td^>^</tr^>
    SET FILE=template.html  :: file to look in

    FINDSTR %FINDWHAT% %FILE% >nul
    IF %ERRORLEVEL% EQU 1 GOTO nowork

    MOVE /Y "%FILE%" "%FILE%.bak"
    FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE "%FILE%.bak" ^|FIND /N /I "%FINDWHAT%"`) DO (
      SET LINE=%%A
    )
    FOR /F "tokens=1,2* delims=]" %%S in ("%LINE%") DO SET LINE=%%S  ::read file line by line
        SET /A LINE=%LINE:~1,6%
        SET /A COUNT=1
        FOR /F "USEBACKQ tokens=*" %%A IN (`FIND /V "" ^<"%FILE%.bak"`) DO (
          IF "!COUNT!" NEQ "%LINE%" (
              ECHO %%A>>"%FILE%" :: if the matching string not found, write the line as it is
          ) ELSE (
              ECHO %REPLACEWITH%>>"%FILE%" :: if found, replace the entire line with PROPVAL
          )
          SET /A COUNT+=1
        )
    GOTO end
    :nowork

    :end
)
:sendreport
echo "done"

输出.txt

R560359C    BA0001  Done    113121  24046   113121  24047
R560902C    BAS0006 Done    113121  24647   113121  45726
R560902C    BAS0005 Done    113121  24647   113121  45155
R560902C    BAS0009 Done    113121  45754   113121  70022

模板.html

<html>
<body>
<table>
<tr id='R560902CBAS0009'><td>R093021</td><td>BASJ1TNA</td><td>not_started</td><td>-</td><td>-</td><td>-</td><td>-</td></tr>
<tr id='R6213G04BA0001'><td>R6213G04</td><td>BA0001</td><td>not_started</td><td>-</td><td>-</td><td>-</td><td>-</td></tr>
<tr id='R560359BBA0001'><td>R560359B</td><td>BA0001</td><td>not_started</td><td>-</td><td>-</td><td>-</td><td>-</td></tr>
<tr id='R560902CBAS0006'><td>R560902C</td><td>BAS0006</td><td>not_started</td><td>-</td><td>-</td><td>-</td><td>-</td></tr>
<tr id='R560902CBAS0005'><td>R560902C</td><td>BAS0005</td><td>not_started</td><td>-</td><td>-</td><td>-</td><td>-</td></tr>
<tr id='R560359CBA0001'><td>R560902C</td><td>BAS0009</td><td>not_started</td><td>-</td><td>-</td><td>-</td><td>-</td></tr>
</table>
</body>
</html>
4

1 回答 1

3
@ECHO OFF
setlocal
for /F "tokens=1,2,3,4,5,6,7" %%i in (output.txt) do call :process %%i %%j %%k %%l %%m %%n %%o
goto :sendreport

:: procedure to prepare report

:process
    SETLOCAL EnableDelayedExpansion

    set UBENAME=%1
    set UBEVER=%2
    set UBESTAT=%3
    set RUNDATE=%4
    set STARTTIME=%5
    set ENDTIME=%6
    set TOTALTIME=%7

:: letter to find in the file
    SET FINDWHAT=%UBENAME%%UBEVER%
    SET REPLACEWITH=^<tr^>^<td^> %UBENAME% ^</td^>^<td^> %UBEVER% ^</td^>^<td^> %UBESTAT% ^</td^>^<td^> %RUNDATE% ^</td^>^<td^> %STARTTIME% ^</td^>^<td^> %ENDTIME% ^</td^>^<td^> %TOTALTIME% ^</td^>^</tr^>
:: file to look in
    SET FILE=template.html

    FINDSTR %FINDWHAT% %FILE% >nul
    IF %ERRORLEVEL% EQU 1 GOTO nowork

    MOVE /Y "%FILE%" "%FILE%.bak" >nul
    FOR /F "delims=" %%A IN ('TYPE "%FILE%.bak"') DO (
     ECHO "%%A"|FIND /i "%findwhat%" >NUL
     IF ERRORLEVEL 1 (>>"%file%" echo %%A
     ) else (
      >>"%file%" echo !replacewith!
     )
    )
GOTO :eof

:sendreport
echo "done"
GOTO :eof

这应该可以完成工作-如果我了解您通过四处走动来尝试做的事情。最好说出问题出在哪里,而不是要求解决无效的治疗方法。

  • 逐行抓取文件。
  • 寻找目标字符串
  • 如果没有找到,就施乐
  • 如果找到,吐出替换线。

诀窍是使用延迟扩展来防止替换行被解释。使用!var!,解析器不知道变量包含重定向,因此它不反对。在执行时,解析器已经完成了它的工作。

于 2013-05-02T12:59:57.677 回答