バッチファイルによる自動処理では、ログファイルの内容を判定して次の処理を切り替える場面が頻繁にあります。「ERRORが含まれていれば担当者にメールを送る」「行数が5000行を超えたらログをローテーションする」「警告件数が10件以上なら処理を中断する」といった制御がバッチファイルだけで実現できます。
この記事では、行数カウントの複数手法・findstrによるキーワード検索・エラー件数の集計・AND/OR複合条件・特定行の抽出まで、実務で使えるパターンを体系的に解説します。FINDSTRコマンドの使い方完全ガイドも合わせて読むと、findstrの全オプションを把握できます。
行数カウントの3つの方法(find /v “”・for /f・PowerShell連携)、行数による条件分岐とログローテーション連携、findstrでのキーワード存在確認と件数カウント(find /c)、複数キーワードのAND/OR判定・正規表現検索、最終行・最新エラー行の抽出、実践的な自動監視スクリプトの実装例まで網羅
ログファイルの行数をカウントする方法
バッチファイルで行数を取得するには主に3つの方法があります。用途と精度に応じて使い分けましょう。
方法1:find /c “” で高速カウント(推奨)
find /c "" は空文字列にマッチする行をカウントします。空行も含む全行数を取得でき、最も高速でシンプルな方法です。
@echo off
setlocal enabledelayedexpansion
set "LOGFILE=C:\logs\app.log"
:: find /c "" で行数を含む文字列を取得 → 数値だけ切り出す
for /f "tokens=3" %%N in ('find /c "" "%LOGFILE%"') do (
set /a LINE_COUNT=%%N
)
echo 行数: !LINE_COUNT! 行
:: 閾値での分岐
if !LINE_COUNT! GTR 5000 (
echo [WARNING] 5000行を超えました。ログローテーションを実行します。
:: call :rotate_log
) else (
echo [OK] 行数は正常範囲内です。
)
endlocal
find /c "" ファイル名 を実行すると、---------- C:\logs\app.log: 1234 という形式で出力されます。for /f "tokens=3" で3番目のトークン(行数の数値部分)を切り出しています。方法2:for /f でループカウント(行ごとに処理したいとき)
ログの各行を読み取りながら同時にカウントしたい場合は for /f 方式を使います。行内容にアクセスしながらカウントできるのが利点です。
@echo off
setlocal enabledelayedexpansion
set "LOGFILE=C:\logs\app.log"
set /a LINE_COUNT=0
set /a ERROR_COUNT=0
for /f "usebackq delims=" %%L in ("%LOGFILE%") do (
set /a LINE_COUNT+=1
:: 各行にERRORが含まれているかチェックしながらカウント
echo %%L | findstr /i "ERROR" > nul
if not errorlevel 1 set /a ERROR_COUNT+=1
)
echo 総行数 : !LINE_COUNT! 行
echo エラー行数: !ERROR_COUNT! 件
endlocal
for /f は空行をスキップする仕様です。空行を含む正確な行数が必要な場合は find /c "" を使ってください。空行もカウントしたい場合は for /f "delims=" でも空行はスキップされるため、find /c 方式が確実です。方法3:PowerShell を呼び出す(Unicode対応・大ファイル向け)
UTF-8やUnicode形式のログ、数百MBの大容量ログには PowerShell を使う方が確実です。
@echo off
setlocal
set "LOGFILE=C:\logs\unicode_app.log"
:: PowerShell で行数を取得(UTF-8含む任意エンコーディング対応)
for /f %%N in ('powershell -NoProfile -Command "(Get-Content -Path '%LOGFILE%' -Encoding UTF8).Count"') do (
set /a LINE_COUNT=%%N
)
echo 行数: %LINE_COUNT% 行
endlocal
| 方法 | 速度 | 空行カウント | 文字コード対応 | 用途 |
|---|---|---|---|---|
find /c "" |
◎ 最速 | ○ 含む | △ Shift-JIS前提 | 最もシンプルな行数取得 |
for /f ループ |
○ 普通 | ✕ スキップ | △ Shift-JIS前提 | 行ごとに処理しながらカウント |
| PowerShell | ○ 普通 | ○ 含む | ◎ 指定可能 | Unicode・大容量ログ対応 |
行数に応じた多段階の条件分岐
取得した行数を使って処理を多段階に分岐できます。バッチファイルで条件分岐する方法完全ガイドと組み合わせることで、複雑な制御フローも実装できます。
@echo off
setlocal enabledelayedexpansion
set "LOGFILE=C:\logs\app.log"
set /a WARN_LINE=1000
set /a ROTATE_LINE=5000
set /a CRITICAL_LINE=10000
:: 行数取得
for /f "tokens=3" %%N in ('find /c "" "%LOGFILE%"') do set /a LINES=%%N
echo ログ行数: !LINES! 行
if !LINES! GEQ %CRITICAL_LINE% (
echo [CRITICAL] 行数が%CRITICAL_LINE%行を超えました。緊急ローテーションします。
call :do_rotate
call :send_alert CRITICAL !LINES!
goto :end
)
if !LINES! GEQ %ROTATE_LINE% (
echo [WARN] 行数が%ROTATE_LINE%行を超えました。ローテーションします。
call :do_rotate
goto :end
)
if !LINES! GEQ %WARN_LINE% (
echo [INFO] 行数が%WARN_LINE%行を超えました。要監視状態です。
goto :end
)
echo [OK] 行数は正常範囲内です。
:end
endlocal
exit /b 0
:do_rotate
echo ログローテーション実行中...
:: ここにローテーション処理を記述
exit /b 0
:send_alert
echo アラート送信: %1 - 行数 %2
exit /b 0
GTR は「より大きい(超える)」、GEQ は「以上(含む)」です。「5000行を超えたら」は GTR 5000、「5000行以上なら」は GEQ 5000 を使います。数値比較の詳細はバッチファイルで条件分岐する方法完全ガイドを参照してください。findstr によるキーワード検索と存在確認
findstr はバッチファイルでの文字列検索の基本コマンドです。ログにキーワードが含まれているかの判定から、マッチ行の件数カウントまで幅広く使えます。
キーワードの存在確認(0件か1件以上か)
@echo off
setlocal
set "LOGFILE=C:\logs\app.log"
set "KEYWORD=ERROR"
:: findstr でキーワードを検索(結果は nul へ捨てる)
findstr /i "%KEYWORD%" "%LOGFILE%" > nul 2>&1
if errorlevel 1 (
echo [OK] "%KEYWORD%" は見つかりませんでした。
) else (
echo [NG] "%KEYWORD%" が検出されました。エラー対応処理を実行します。
:: call :handle_error
)
endlocal
よく使う findstr オプション
| オプション | 説明 | 例 |
|---|---|---|
/i |
大文字・小文字を区別しない | findstr /i "error"(ERROR・Error・error すべて対象) |
/c:"文字列" |
スペースを含むフレーズを検索 | findstr /c:"disk full" |
/v |
キーワードを含まない行を抽出 | findstr /v "OK"(OK以外の行を出力) |
/n |
行番号付きで出力 | findstr /n "ERROR"(3:ERROR発生 のように表示) |
/r |
正規表現検索 | findstr /r "ERR[0-9][0-9]" |
/s |
サブフォルダも再帰検索 | findstr /s "ERROR" C:\logs\*.log |
/l |
リテラル検索(正規表現を無効化) | findstr /l "a.b"(a.b のみ・a任意文字bにはマッチしない) |
FINDSTRコマンドの使い方完全ガイドでは、findstrの全オプション・正規表現パターン・複数ファイル横断検索など、実務で役立つ使い方を網羅しています。
キーワードの出現件数をカウントして閾値判定
「ERRORが1件でもあれば」ではなく「ERRORが10件以上なら緊急対応」という判定には、find /c コマンドでキーワードの出現行数をカウントします。
@echo off
setlocal enabledelayedexpansion
set "LOGFILE=C:\logs\app.log"
set "KEYWORD=ERROR"
set /a WARN_COUNT=5
set /a CRIT_COUNT=20
:: find /c でキーワードを含む行数をカウント
for /f "tokens=3" %%N in ('find /c /i "%KEYWORD%" "%LOGFILE%"') do (
set /a ERR_COUNT=%%N
)
echo ERRORの件数: !ERR_COUNT! 件
if !ERR_COUNT! GEQ %CRIT_COUNT% (
echo [CRITICAL] ERROR が %CRIT_COUNT% 件以上。緊急対応が必要です。
call :send_mail CRITICAL !ERR_COUNT!
exit /b 1
)
if !ERR_COUNT! GEQ %WARN_COUNT% (
echo [WARNING] ERROR が %WARN_COUNT% 件以上です。
call :send_mail WARNING !ERR_COUNT!
exit /b 0
)
if !ERR_COUNT! GTR 0 (
echo [INFO] ERROR が !ERR_COUNT! 件あります。
exit /b 0
)
echo [OK] エラーなし
exit /b 0
:send_mail
echo メール送信: レベル=%1 件数=%2
exit /b 0
endlocal
複数のキーワードをそれぞれカウント
@echo off
setlocal enabledelayedexpansion
set "LOGFILE=C:\logs\app.log"
:: 各キーワードの件数を取得
for /f "tokens=3" %%N in ('find /c /i "ERROR" "%LOGFILE%"') do set /a CNT_ERROR=%%N
for /f "tokens=3" %%N in ('find /c /i "WARNING" "%LOGFILE%"') do set /a CNT_WARN=%%N
for /f "tokens=3" %%N in ('find /c /i "FATAL" "%LOGFILE%"') do set /a CNT_FATAL=%%N
echo ── ログ解析結果 ──────────────────────
echo FATAL : !CNT_FATAL! 件
echo ERROR : !CNT_ERROR! 件
echo WARNING: !CNT_WARN! 件
:: FATAL が1件でもあれば最優先対応
if !CNT_FATAL! GTR 0 (
echo [CRITICAL] FATALエラーを検出しました。即時対応してください。
exit /b 2
)
:: ERROR が10件以上なら警告
if !CNT_ERROR! GEQ 10 (
echo [ERROR] エラーが多発しています。
exit /b 1
)
echo [OK] 重大なエラーはありません。
endlocal
複数キーワードの AND・OR 複合判定
実務では「ERRORを含み、かつRETRYを含まない行」「WARNINGまたはERRORを含む行」といった複合条件が必要になることがあります。
AND 条件:すべてのキーワードを含む判定
@echo off
setlocal
set "LOGFILE=C:\logs\app.log"
:: "ERROR" かつ "DATABASE" を含む行があるか(パイプで絞り込み)
findstr /i "ERROR" "%LOGFILE%" | findstr /i "DATABASE" > nul 2>&1
if errorlevel 1 (
echo DB関連のERRORは見つかりませんでした。
) else (
echo [NG] DBに関連するERRORを検出しました。
)
endlocal
OR 条件:いずれかのキーワードを含む判定
@echo off
setlocal
set "LOGFILE=C:\logs\app.log"
:: "ERROR" または "FATAL" または "CRITICAL" のいずれかを含む行
findstr /i "ERROR FATAL CRITICAL" "%LOGFILE%" > nul 2>&1
if errorlevel 1 (
echo 重大なキーワードは見つかりませんでした。
) else (
echo [NG] 重大なエラーを検出しました。
)
endlocal
findstr "ERROR FATAL" は「ERRORまたはFATAL」を含む行を検索します(OR条件)。スペースを含むフレーズを検索する場合は /c:"disk full" のように /c: オプションを使ってください。NOT 条件:キーワードを含まない行を対象にする
@echo off
setlocal
set "LOGFILE=C:\logs\app.log"
:: "OK" を含まない行(= 問題がある可能性の行)をカウント
for /f "tokens=3" %%N in ('findstr /v /i "OK" "%LOGFILE%" ^| find /c ""') do (
set /a NOT_OK_COUNT=%%N
)
echo OK以外の行数: %NOT_OK_COUNT% 件
:: "ERROR" を含むが "RETRY成功" を含まない行
findstr /i "ERROR" "%LOGFILE%" | findstr /v /i "RETRY成功" > nul 2>&1
if errorlevel 1 (
echo リカバリ不能なERRORはありません。
) else (
echo [NG] リトライでも解消されていないERRORがあります。
)
endlocal
正規表現による高度なパターン検索
@echo off setlocal set "LOGFILE=C:\logs\app.log" :: ERR + 4桁数字のエラーコードパターンを検索(例: ERR1023・ERR5502) findstr /r /i "ERR[0-9][0-9][0-9][0-9]" "%LOGFILE%" > nul 2>&1 if not errorlevel 1 echo エラーコードパターンを検出しました。 :: 特定の日時形式を含む行を検索(2024-xx-xx 形式) findstr /r "2[0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]" "%LOGFILE%" > nul 2>&1 if not errorlevel 1 echo 日付形式の行を検出しました。 :: IPアドレスのパターンを検索 findstr /r "[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*" "%LOGFILE%" > nul 2>&1 if not errorlevel 1 echo IPアドレスを含む行を検出しました。 endlocal
findstrの正規表現(
/r)はPOSIX風の独自実装で、一般的な正規表現と異なる点があります。+(1回以上)や \d(数字)は使えません。複雑な正規表現が必要な場合は PowerShell の Select-String を使う方が確実です。特定行の抽出:最終行・先頭行・直近Nエラー行
エラーが発生した際、「最後に出力されたエラー内容」だけを取得してメール通知に含めるといった用途で、特定行の抽出が役立ちます。
最終行だけを取得する
@echo off
setlocal enabledelayedexpansion
set "LOGFILE=C:\logs\app.log"
set "LAST_LINE="
:: for /f でファイルを最後まで読み、最後の値が最終行になる
for /f "usebackq delims=" %%L in ("%LOGFILE%") do (
set "LAST_LINE=%%L"
)
echo 最終行: !LAST_LINE!
endlocal
最新のエラー行だけを取得する
@echo off
setlocal enabledelayedexpansion
set "LOGFILE=C:\logs\app.log"
set "LAST_ERROR="
:: ERRORを含む行を順次読み込み、最後のものが最新エラー
for /f "usebackq delims=" %%L in ('findstr /i "ERROR" "%LOGFILE%"') do (
set "LAST_ERROR=%%L"
)
if defined LAST_ERROR (
echo 最新のエラー行:
echo !LAST_ERROR!
) else (
echo エラーは見つかりませんでした。
)
endlocal
直近N件のエラー行をファイルに保存する
@echo off
setlocal
set "LOGFILE=C:\logs\app.log"
set "OUTPUT=C:\logs\recent_errors.txt"
set /a N=20
:: PowerShell で直近20件のERROR行を取得
powershell -NoProfile -Command ^
"Get-Content '%LOGFILE%' | Select-String 'ERROR' | Select-Object -Last %N% | Out-File '%OUTPUT%' -Encoding UTF8"
echo 直近%N%件のエラーを %OUTPUT% に保存しました。
endlocal
特定日時以降のエラーだけを判定する
@echo off
setlocal enabledelayedexpansion
set "LOGFILE=C:\logs\app.log"
:: 今日の日付を YYYY-MM-DD 形式で取得
for /f "tokens=1,2,3 delims=/" %%a in ("%DATE%") do (
set "TODAY=%%a-%%b-%%c"
)
:: ※環境によって %DATE% の形式が異なるため注意(例: 2024/01/15 や 2024-01-15)
:: wmic を使う場合:
:: for /f %%D in ('wmic os get LocalDateTime ^| findstr "^[0-9]"') do set "DT=%%D"
:: set "TODAY=!DT:~0,4!-!DT:~4,2!-!DT:~6,2!"
:: 今日の日付を含むERROR行をカウント
for /f "tokens=3" %%N in ('findstr /i "%TODAY%" "%LOGFILE%" ^| find /c /i "ERROR"') do (
set /a TODAY_ERRORS=%%N
)
echo 本日 (%TODAY%) のERROR件数: !TODAY_ERRORS! 件
endlocal
実践パターン:完全自動ログ監視スクリプト
行数チェック・キーワード件数判定・通知・ログ退避をすべて組み合わせた、タスクスケジューラで定期実行できる完成版スクリプトです。ログファイルを監視して自動処理するバッチファイル完全ガイドも合わせて参照すると、より高度な監視パターンを学べます。
@echo off
setlocal enabledelayedexpansion
:: ============================================================
:: log_monitor.bat - ログファイル自動監視スクリプト
:: タスクスケジューラで5分ごとに実行する想定
:: ============================================================
:: ── 設定 ────────────────────────────────────────────────
set "LOGFILE=C:\logs\app.log"
set "REPORT_DIR=C:\logs\reports"
set "ARCHIVE_DIR=C:\logs\archive"
set "MONITOR_LOG=C:\logs\monitor.log"
:: 閾値設定
set /a LINE_WARN=5000
set /a LINE_ROTATE=10000
set /a ERR_WARN=5
set /a ERR_CRIT=20
:: ── 初期化 ──────────────────────────────────────────────
if not exist "%REPORT_DIR%" mkdir "%REPORT_DIR%"
if not exist "%ARCHIVE_DIR%" mkdir "%ARCHIVE_DIR%"
set "NOW=%DATE% %TIME%"
echo [%NOW%] 監視開始 >> "%MONITOR_LOG%"
:: ── ログファイルの存在確認 ──────────────────────────────
if not exist "%LOGFILE%" (
echo [%NOW%] [ERROR] ログファイルが見つかりません: %LOGFILE% >> "%MONITOR_LOG%"
exit /b 1
)
:: ── 行数チェック ─────────────────────────────────────────
for /f "tokens=3" %%N in ('find /c "" "%LOGFILE%"') do set /a LINES=%%N
echo [%NOW%] 行数: !LINES! 行 >> "%MONITOR_LOG%"
:: ── エラー件数チェック ───────────────────────────────────
for /f "tokens=3" %%N in ('find /c /i "ERROR" "%LOGFILE%"') do set /a CNT_ERR=%%N
for /f "tokens=3" %%N in ('find /c /i "FATAL" "%LOGFILE%"') do set /a CNT_FATAL=%%N
for /f "tokens=3" %%N in ('find /c /i "WARNING" "%LOGFILE%"') do set /a CNT_WARN=%%N
echo [%NOW%] FATAL:%CNT_FATAL% ERROR:!CNT_ERR! WARNING:!CNT_WARN! >> "%MONITOR_LOG%"
:: ── FATAL チェック(最優先) ─────────────────────────────
if !CNT_FATAL! GTR 0 (
echo [%NOW%] [CRITICAL] FATAL検出: !CNT_FATAL! 件 >> "%MONITOR_LOG%"
call :save_report CRITICAL
call :notify_slack CRITICAL "FATAL %CNT_FATAL%件"
exit /b 2
)
:: ── ERROR 件数による判定 ─────────────────────────────────
if !CNT_ERR! GEQ %ERR_CRIT% (
echo [%NOW%] [CRITICAL] ERRORが%ERR_CRIT%件以上: !CNT_ERR! 件 >> "%MONITOR_LOG%"
call :save_report ERROR_CRITICAL
call :notify_slack CRITICAL "ERROR %ERR_CRIT%件以上"
exit /b 1
)
if !CNT_ERR! GEQ %ERR_WARN% (
echo [%NOW%] [WARNING] ERRORが%ERR_WARN%件以上: !CNT_ERR! 件 >> "%MONITOR_LOG%"
call :save_report ERROR_WARNING
)
:: ── 行数による判定 ───────────────────────────────────────
if !LINES! GEQ %LINE_ROTATE% (
echo [%NOW%] ログローテーション実行 >> "%MONITOR_LOG%"
call :rotate_log
) else if !LINES! GEQ %LINE_WARN% (
echo [%NOW%] [WARNING] ログが%LINE_WARN%行を超えました >> "%MONITOR_LOG%"
)
echo [%NOW%] 監視完了 >> "%MONITOR_LOG%"
exit /b 0
:: ── サブルーチン ─────────────────────────────────────────
:save_report
:: エラー情報をレポートファイルに保存
set "RPT=%REPORT_DIR%\report_%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%_%TIME:~0,2%%TIME:~3,2%.txt"
echo === ログレポート: %1 === > "%RPT%"
echo 日時: %NOW% >> "%RPT%"
echo 行数: !LINES! >> "%RPT%"
echo ERROR: !CNT_ERR! FATAL: !CNT_FATAL! >> "%RPT%"
echo --- 直近エラー行 --- >> "%RPT%"
findstr /i "ERROR FATAL" "%LOGFILE%" | powershell -Command "$input | Select-Object -Last 10" >> "%RPT%"
exit /b 0
:rotate_log
:: ログをアーカイブしてクリア
set "ARCH=%ARCHIVE_DIR%\app_%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%.log"
copy "%LOGFILE%" "%ARCH%" > nul
:: ログをクリア(新しい空ファイルで上書き)
break > "%LOGFILE%"
echo [%NOW%] ローテーション完了: %ARCH% >> "%MONITOR_LOG%"
exit /b 0
:notify_slack
:: PowerShell で Slack webhook 通知(要: Webhook URL設定)
:: powershell -Command "Invoke-RestMethod -Uri 'https://hooks.slack.com/...' -Method Post -Body (@{text='[%1] %~2'} | ConvertTo-Json)"
echo [通知] %1: %~2
exit /b 0
endlocal
このスクリプトを5分ごとに実行するには、バッチファイルで実行時刻・経過時間をログに記録する完全ガイドで解説している実行時刻記録と組み合わせると、「最後にいつ正常に監視が走ったか」を追跡できます。またバッチファイルでエラー通知メールを自動送信する完全ガイドを参照すると、:notify_slackの部分をメール通知に変更できます。
ワンライナーパターン集
よく使うログ解析パターンを短いコードでまとめました。スクリプトの部品として使えます。
@echo off
setlocal enabledelayedexpansion
set "LOG=C:\logs\app.log"
:: ─── 行数取得 ──────────────────────────────────────────
for /f "tokens=3" %%N in ('find /c "" "%LOG%"') do set /a LINES=%%N
echo 総行数: !LINES!
:: ─── キーワード件数(複数) ───────────────────────────
for /f "tokens=3" %%N in ('find /c /i "ERROR" "%LOG%"') do set /a C_ERR=%%N
for /f "tokens=3" %%N in ('find /c /i "WARNING" "%LOG%"') do set /a C_WARN=%%N
for /f "tokens=3" %%N in ('find /c /i "INFO" "%LOG%"') do set /a C_INFO=%%N
echo ERROR:!C_ERR! / WARNING:!C_WARN! / INFO:!C_INFO!
:: ─── ファイルサイズ取得(バイト)─────────────────────
for %%F in ("%LOG%") do set /a FSIZE=%%~zF
echo ファイルサイズ: !FSIZE! バイト
:: ─── 最終更新日時(更新が止まっていないか確認)────────
for %%F in ("%LOG%") do set "MTIME=%%~tF"
echo 最終更新: !MTIME!
:: ─── 最終行取得 ───────────────────────────────────────
for /f "usebackq delims=" %%L in ("%LOG%") do set "LAST=%%L"
echo 最終行: !LAST!
:: ─── 最新エラー行取得 ─────────────────────────────────
for /f "usebackq delims=" %%L in ('findstr /i "ERROR" "%LOG%"') do set "LASTERR=%%L"
echo 最新ERROR: !LASTERR!
:: ─── ログが空かどうか ─────────────────────────────────
if !LINES!==0 echo ログは空です。
:: ─── 特定文字列で始まる行のカウント(行頭マッチ)───────
for /f "tokens=3" %%N in ('findstr /r "^\[ERROR\]" "%LOG%" ^| find /c ""') do set /a HEAD_ERR=%%N
echo [ERROR]で始まる行: !HEAD_ERR! 件
endlocal
よくある質問(FAQ)
find /c "キーワード" は指定した文字列を含む行数をカウントします。findstr /c:"キーワード" はスペースを含むフレーズをリテラルで検索しますが件数は出力しません。件数カウントには find /c、マッチ行の出力には findstr と使い分けるのが基本です。Get-Content -Tail 1000)、②ログファイルを日次でローテーションして1日分のみ監視対象にする。バッチファイルでログローテーションを実装する方法でローテーションの実装を詳しく解説しています。chcp 65001(UTF-8)または chcp 932(Shift-JIS)をスクリプト冒頭で設定し、バッチファイル自体も同じ文字コードで保存してください。ただしバッチとfindstrの日本語処理は不安定な場合があるため、確実を期すなら PowerShell の Select-String を使うことを推奨します。setlocal enabledelayedexpansion)が必要です。ループ内では %VAR% ではなく !VAR! で変数を参照してください。設定を有効にしてもうまくいかない場合、call を経由する方法もあります:call set /a CNT=%%CNT%%+1。findstr "パターン" ファイル | find /c "" がもっとも確実です。findstrの出力をパイプで find /c ""(全行カウント)に渡すと、マッチした行数が得られます。例:for /f "tokens=3" %%N in ('findstr /i "ERROR" app.log ^| find /c ""') do set /a N=%%Nfor %%F in ("app.log") do set "MTIME=%%~tF" で最終更新日時を取得し、フラグファイルに保存した前回値と比較することで「N分以内に更新されているか」を判定できます。詳しい実装は前回処理の状態を記録して次回に引き継ぐ方法を参照してください。まとめ
バッチファイルによるログ解析の主要パターンをまとめます。
| やりたいこと | コマンド | ポイント |
|---|---|---|
| 行数をカウント | find /c "" ファイル |
tokens=3 で数値を切り出す |
| キーワードの存在確認 | findstr /i "KEY" ファイル > nul |
ERRORLEVEL 1 = 未検出 |
| キーワード件数カウント | find /c /i "KEY" ファイル |
tokens=3 で件数を切り出す |
| AND 条件 | findstr "A" ファイル | findstr "B" |
パイプで絞り込み |
| OR 条件 | findstr "A B C" ファイル |
スペース区切りで OR 検索 |
| NOT 条件 | findstr /v "KEY" ファイル |
一致しない行を出力 |
| 最終行を取得 | for /f ループで最後に残った値 |
空行はスキップされる |
| 最新エラー行 | findstr "ERROR" | for /f で最後の値 |
パイプ経由で絞ってから読む |
ログファイルを監視して自動処理するバッチファイル完全ガイド:ログファイルを定期監視して自動処理するパターン集。
FINDSTRコマンドの使い方完全ガイド:findstrの全オプションと正規表現の使い方。
バッチファイルでログローテーションを実装する方法:ログが肥大化したときのローテーション実装。
バッチファイルでエラー通知メールを自動送信する完全ガイド:エラー検知時のメール・Slack自動通知。
バッチファイルでエラーログを自動収集して保存する方法:エラーログを自動収集してまとめる方法。

