シェルスクリプトでログ内の日時を抽出・比較する方法【日付パースと条件分岐】

シェルスクリプトでログファイルを処理するとき、「指定日時以降のログだけ抽出したい」といったケースは多くあります。この記事では、様々なフォーマットの日付に対応した抽出と比較処理の方法をご紹介します。


1. 前提:対象となる日時フォーマットの例

対象となるログの日時には、以下のような形式があります。

✅ ISO形式(一般的なログやCSVなど)

yamlコピーする編集する2025-03-26 14:55:00

✅ Apache形式のアクセスログ

csharpコピーする編集する[26/Mar/2025:14:55:00 +0900]

✅ エラーログ風の形式

csharpコピーする編集する[Wed Mar 26 14:55:00.123456 2025]

2. 処理方針と全体の流れ

シェルスクリプトでは、次の手順で日時を処理します:

  1. 正規表現で日付を抽出
  2. 抽出した文字列を UNIXタイム に変換
  3. cutoff(比較対象の基準時間)と比較

3. パターン別の対応方法とサンプル

🔹 ① ISO形式(2025-03-26 14:55:00)の場合

awkコピーする編集するmatch($0, /([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2})/, m)
cmd = "date -d \"" m[1] "\" +%s"
cmd | getline t
close(cmd)
if (t >= cutoff) print $0

🔹 ② Apache形式([26/Mar/2025:14:55:00 +0900])の場合

awkコピーする編集するmatch($0, /\[([0-9]{2}\/[A-Za-z]{3}\/[0-9]{4}):/, m)
datetime = m[1]
cmd = "date -d \"" datetime "\" +%s"
cmd | getline t

Apache形式のように : の前で分割するのがポイントです。


🔹 ③ エラーログ風([Wed Mar 26 14:55:00.123456 2025])の場合

awkコピーする編集するmatch($0, /\[[A-Za-z]{3} ([A-Za-z]{3}) ([0-9]{1,2}) ([0-9]{2}:[0-9]{2}:[0-9]{2})\.[0-9]+ ([0-9]{4})\]/, m)
datetime = m[1] " " m[2] " " m[3] " " m[4]
cmd = "date -d \"" datetime "\" +%s"
cmd | getline t

この形式では ミリ秒を無視する のが実用的です。


4. 基準時間(cutoff)を定義する

例えば「90日前以降のログを抽出」したい場合は、以下のようにUNIX時間を取得します。

90日前のcutoff

bashコピーする編集するCUTOFF=$(date -d "90 days ago" +%s)

1時間前のcutoff

bashコピーする編集するCUTOFF=$(date -d "1 hour ago" +%s)

5. 構文テンプレート(まとめ)

以下は、cutoffと日付を比較して抽出する基本テンプレートです。

bashコピーする編集するCUTOFF=$(date -d "90 days ago" +%s)

awk -v cutoff="$CUTOFF" '
{
    if (match($0, /ここに正規表現/, m)) {
        cmd = "date -d \"" m[1] "\" +%s"
        cmd | getline t
        close(cmd)
        if (t >= cutoff) {
            print $0
        }
    }
}
' logfile.log

6. まとめ

処理内容解説
ログから日時を抽出awk + 正規表現を使用
日付の比較方法date -d でUNIXタイムに変換して比較
cutoff(基準時間)date -d "◯日前" +%s で定義
応用ISO, Apache形式、エラーログ形式にも対応可能

備考: この処理はログクレンジング、監査用フィルタリング、アーカイブ対象の抽出など、さまざまな場面で活用できます。用途に応じて正規表現とcutoffの条件を調整してください。

Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です