0

申し訳ありませんが、ここで同様の質問があったことは知っていますが、基本的には、バッチスクリプト内のテキストファイルを読み取って、ファイルに書き込まれた内容を評価しようとしています。

このジョブは、ファイルをプリンターに送信する印刷ジョブです。コマンドからの出力をログファイルにエコーします。次に、出力が何であるかを読みたいと思います。エラーが発生した場合は、メールを送信して、動作が停止したことを確認します。

常にファイルの最後に追加されるので、エラーがある場合は、最後の行から4番目が「Error:」で始まります。だから私の質問は、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.

ファイルの最後に1行の空白行が残るので、最後の行から4を引いたものを使用します。

ありがとうございました

4

4 に答える 4

0

ログファイルの下から4行目を読み始めたい場合は、ログファイルの行数を数え、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風のファイル読み取りに置き換わる同じスクリプトです。

@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

バッチファイルの行として:

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%

ファイルの最後の 4 行目である場合にのみ行を取得する必要があります。「+ 3」は必要な行数です (つまり、マイナス 1)。

しかし、これがログファイルのように見える場合、エラーの後に(さらなるジョブのために)さらなるエントリが表示される可能性がある(私が想像する)可能性があるため、 のターゲットはLine beginning "Error:"最後から4番目ではない可能性があることを覚えておいてください. ..

OTOH、最初に投稿した行を使用して、「エラー:...」行が表示されると、毎回検出されます-メール送信手順でログファイルをリセットする必要があります(既存を保存して再作成します)空の?)

于 2013-03-19T15:53:08.817 に答える
0

ループのない解決策(エラーがあるかどうかをテストします):

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

そして、このコードは最後の行の前の 4 行目のみエラーをテストします。

@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 に答える
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 のどちらでループしても、ログ ファイル内の行数をカウントし、ログ ファイルを 1 行ずつループするこれらの他のすべての方法よりもはるかに効率的です。

于 2013-03-20T13:59:27.570 に答える