5

after struggling for 2 days I still have not been able to find solution to my problem with windows batch script.

what I want to do is read the html file line by line and if the matching keyword found in a particular line, then replace that line with something (html tags and variable combination)

No matter whatever I do, I always get some error "< was expected at this time" whenever I try to push html tags to the file. Looks like batch script does not like html.

Here is my code:

script.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"

output.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

template.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>
6
  • At first, you cannot think comments on bat files are equal comments on another languages: if you put on same line of a command, it will be processed as a part of it... Commented May 2, 2013 at 12:21
  • Also, use "pause" command do "debug" (to discover where is the error) that kind of file... Commented May 2, 2013 at 12:24
  • Well, the issue is in FOR /F "USEBACKQ tokens=*" %%A IN (FIND /V "" ^<"%FILE%.bak") DO (... I'm trying to understand what is wrong... Commented May 2, 2013 at 12:29
  • FIND /V "" ^<"%FILE%.bak" has same effects as FIND /V "" "%FILE%.bak"... Commented May 2, 2013 at 12:36
  • 1
    Finally, remember about the use of ! when using SETLOCAL EnableDelayedExpansion. I think that was the issue... Commented May 2, 2013 at 13:00

1 Answer 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

This should do the job - if I understand what you're attempting to do by going all around the houses. Best to say whay the problem is rather than ask for a fix to a cure that doesn't work.

  • Grab the file, line-by-line.
  • Look for the target string
  • if not found, just xerox the line
  • if found, spit out the replacement line.

The trick being to use delayed-expansion to prevent the replacement line from being interpreted. With !var!, the parser doesn't know that the variable contains redirects, so it doesn't object. At execution time, the parser's already done its job.

Sign up to request clarification or add additional context in comments.

2 Comments

Ok, it is more polite answer. I gave up on mine :)
Thanks a lot, it did the trick. I knew that !! delimeter used for runtime stuff but did not know that it canbe used like this, and parser does skip it. Thanks Peter, you saved me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.