0

抱歉,我知道这里有人问过类似的问题,但基本上我正在尝试读取批处理脚本中的文本文件并评估写入文件的内容。

该作业是一个将文件发送到打印机的打印作业,我让它将命令的输出回显到日志文件。然后我想读一下输出是什么,如果有错误,我会发送一封电子邮件,以便我们知道什么时候停止工作。

它总是附加到文件的末尾,所以我知道如果有错误,最后一行的第 4 行将以“错误:”开头。所以我的问题是如何将其读入变量,以便执行 IF 语句。我已经对电子邮件部分进行了排序,它只是从我正在努力处理的文件中读取。

任何帮助将非常感激。以下是出现错误时文件内容的示例:

---- 
C:\XG1\DGS01\prints\000000398200001.XG1 
19/03/2013 
15:02
        1 file(s) copied.
Error: print server unreachable or specified printer does not exist.

        1 file(s) moved.

它在文件末尾留下一个空白行,所以我将使用最后一行减去 4。

谢谢

4

4 回答 4

0

as a line in your batch file:

for /f "tokens=1*delims=:" %%i in (thenameofyourfile) do if "%%i"=="Error" set message=%%j
echo message was "%message%"

Actually, that will report if ANY lines are in the format you describe.

@ECHO OFF
SETLOCAL
(SET message=)
FOR /f "tokens=1,2*delims=[]:" %%i IN (
 ' TYPE thenameofyourfile^|find /n /v "" '
 ) DO (
 SET lastline=%%i
 IF "%%j"=="Error" SET errorline=%%i&SET message=%%k
 )
SET /a target=%errorline% + 3
IF %target% neq %lastline% (SET message=)
IF DEFINED message ECHO error found %message%

should get the line ONLY if it's the fourth last line in the file - the "+ 3" being the line-count required (well, minus 1)

BUT - remember that if this is, as it seems, a log file that it's possible (I'd imagine) that further entries may appear AFTER the error (for further jobs) so the target for the Line beginning "Error:" may not be the fourth-last...

OTOH, using the line(s) I first posted, once an "Error:..." line appears, it will be detected EVERY time - you'd need to reset the logfile in your mail-send procedure (save existing & recreate empty?)

于 2013-03-19T15:53:08.817 回答
0

我相信检查错误的最快且资源最少的方法是使用GNU tail。如果可以,请获取 .zip 二进制文件并将其放入tail.exe您的路径或批处理脚本可以访问的位置。然后:

@echo off
setlocal

tail -n 4 printerlog.log | find /i "Error:" >NUL && (
    echo Error found.  Sending email.
    rem do email stuff
)

或者,如果您希望为您的电子邮件捕获错误文本:

@echo off
setlocal

for /f "delims=" %%I in ('tail -n 4 printerlog.log ^| find /i "Error:"') do (
    echo Error found: %%I
    rem do email stuff
    goto :EOF
)

tail比所有其他计算日志文件行数和逐行循环日志文件的方法(无论是批处理循环还是在 JScript 中循环)都高效得多。

于 2013-03-20T13:59:27.570 回答
0

如果您想从日志文件底部开始读取第四行,您可以计算日志文件中的行数,减去 4,然后more +%count%得到日志的尾部。

@echo off
setlocal
set logfile=printerlog.log

for /f "tokens=2 delims=:" %%I in ('find /c /v "" "%logfile%"') do set lines=%%I
set /a "tail4=%lines% - 4"

for /f %%I in ('more +%tail4% "%logfile%" ^| find /i "Error:"') do (
    rem do your email voodoo here
)

如果您的日志文件将超过 65,535 行,我建议使用 JScript 或 VBScript 循环文件而不是批处理循环。跳过那么多行more会导致more崩溃,所以你必须逐行循环并增加一个计数器。但是,批处理for循环非常慢。


more这是用 JScript-ish 文件读取替换的相同脚本。

@if (@a==@b) @end /*
:: batch portion

@echo off
setlocal
set logfile=printerlog.log

for /f "tokens=2 delims=:" %%I in ('find /c /v "" "%logfile%"') do set lines=%%I
set /a "tail4=%lines% - 4"

for /f "delims=" %%I in ('cscript /nologo /e:jscript "%~f0" %tail4% "%logfile%" ^| find /i "Error:"') do (
    rem do your email voodoo here
    rem %%I contains the matching line.

    rem After one match, stop processing further
    goto :EOF
)

goto :EOF

::JScript portion */
var i=0, fso = new ActiveXObject("Scripting.FileSystemObject").OpenTextFile(WSH.Arguments(1),1);
while (!fso.AtEndOfStream) {
    if (i++ < WSH.Arguments(0)) fso.SkipLine();
    else WSH.Echo(fso.ReadLine());
}
fso.Close();
于 2013-03-19T16:12:04.210 回答
0

没有任何循环的解决方案(测试是否有任何错误):

@findstr Error: printer.log >nul 2>&1
@if %errorlevel% equ 0 echo Send email now!

这段代码只测试最后一行之前的第四行是否有错误:

@echo off &setlocal enabledelayedexpansion
for /f %%i in ('findstr /n "^" printer.log') do (
set line4=!line3!&set line3=!line2!&set line2=!line1!&set line1=%%i)
echo %line4%|findstr Error: >nul 2>&1
if %errorlevel% equ 0 echo Send email now!
于 2013-03-19T16:35:56.750 回答