使用批处理脚本从文本文件中读取特定行上的第一个单词,然后输入if语句

时间:2013-03-19 15:49:00

标签: batch-file text-files

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

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

它总是附加到文件的末尾,所以我知道是否有错误,最后一行的第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 个答案:

答案 0 :(得分:0)

作为批处理文件中的一行:

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

实际上,如果任何行都采用您描述的格式,则会报告。

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

是文件中的第四行 - " + 3"是所需的行数(好,减去1)

但是 - 请记住,如果这看起来是一个日志文件,它可能(我想象)在错误之后可能出现更多条目(对于其他工作)所以目标是Line beginning "Error:"可能不是第四个......

OTOH,使用我首次发布的一行,一旦出现"错误:......"出现行,它会被检测到 - 您需要在邮件发送过程中重置日志文件(保存现有的&重新创建空?)

答案 1 :(得分:0)

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

@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循环非常慢。


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

@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();

答案 2 :(得分: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!

答案 3 :(得分: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循环。