日時範囲指定ログ抽出awkコマンド用ファイル作成シェルスクリプト

estis2012/02/09 (木) 02:14 に投稿

改良版 https://blog.musirao.net/node/1253 を参照ください。 日時範囲を指定してのログ抽出依頼が頻繁にあるので、awk で作業するときの指定内容を作成するシェルスクリプトを作ってみた。 とりあえず対象はメールログ(ログの第2フィールドが日付、第3フィールドが:区切りで時刻[hh:mm:ss]となっているもの)。 このバージョンでは、同月内のみ対応。 簡便な入力値チェックを行っている(2月の日付チェックが手抜き)。

#!/bin/bash

thisVer (){
        if [ $fromMonth -ne $toMonth ];then
                echo "<(_ _)> このバージョンでは、同月内のみの対応です。ごめんなさい。"
                exit 1
        fi
}

iInput (){
        if [ $i -ne 0 ]; then
                echo "入力した値が間違っています。再入力してください。"
        fi
}

check_M (){
        i=0
        checkMonth=-1
        until [ $checkMonth -ge 1 -a $checkMonth -le 12 ]
        do
                iInput
                echo -n $1
                read checkMonth
                i=1
        done
        return $checkMonth
}

check_D (){
        check_D_Re (){
                iInput
                echo -n $D_string
                read checkDay
                i=1
        }
        i=0
        D_string=$2
        checkDay=-1
        case $1 in
                2 ) until [ $checkDay -ge 1 -a $checkDay -le 29 ]
                        do
                                check_D_Re
                        done ;;
                4 | 6 | 9 | 11 ) until [ $checkDay -ge 1 -a $checkDay -le 30 ]
                        do
                                check_D_Re
                        done ;;
                * ) until [ $checkDay -ge 1 -a $checkDay -le 31 ]
                        do
                                check_D_Re
                        done ;;
        esac
        return $checkDay
}

check_H (){
        i=0
        checkHour=-1
        until [ $checkHour -ge 0 -a $checkHour -le 23 ]
        do
                iInput
                echo -n $1
                read checkHour
                i=1
        done
        return $checkHour
}

check_T (){
        i=0
        checkTime=-1
        until [ $checkTime -ge 0 -a $checkTime -le 59 ]
        do
                iInput
                echo -n $1
                read checkTime
                i=1
        done
        return $checkTime
}

echo "日時範囲を指定してください。"
check_M "開始月:"
fromMonth=$?
check_D $fromMonth "開始日:"
fromDay=$?
check_H "開始時:"
fromHour=$?
check_T "開始分:"
fromMin=$?
check_T "開始秒:"
fromSec=$?
check_M $toMonth "終了月:"
toMonth=$?

thisVer

check_D $toMonth "終了日:"
toDay=$?
check_H "終了時:"
toHour=$?
check_T "終了分:"
toMin=$?
check_T "終了秒:"
toSec=$?

FROM=$(date --date "$fromMonth/$fromDay $fromHour:$fromMin:$fromSec" +%s)
TO=$(date --date "$toMonth/$toDay $toHour:$toMin:$toSec" +%s)

if [ $TO -lt $FROM ]; then
        echo "エラー! 終了日時が開始日時より前になっています。"
        exit 1
fi

if [ $fromDay -eq $toDay ]; then
        if [ $fromHour -eq $toHour ]; then
                if [ $fromMin -eq $toMin ]; then
                        if [ $fromSec -eq $toSec ]; then
                                echo "{split(\$3, a, \":\");if(\$2==$fromDay&&a[1]==$fromHour&&a[2]==$fromMin&&a[3]==$fromSec)print}"
                        else
                                echo "{split(\$3, a, \":\");if(\$2==$fromDay&&a[1]==$fromHour&&a[2]==$fromMin&&a[3]>=$fromSec&&a[3]<=$toSec)print}"
                        fi
                else
                        echo "{split(\$3, a, \":\");if((\$2==$fromDay&&a[1]==$fromHour)&&((a[2]==$fromMin&&a[3]>=$fromSec)||(a[2]>$fromMin&&a[2]<$toMin)||(a[2]==$toMin&&a[3]<=$toSec)))print}"
                fi
        else
                echo "{split(\$3, a, \":\");if(\$2==$fromDay&&((a[1]==$fromHour&&a[2]==$fromMin&&a[3]>=$fromSec)||(a[1]==$fromHour&&a[2]>$fromMin)||(a[1]>$fromHour&&a[1]<$toHour)||(a[1]==$toHour&&a[2]<$toMin)||(a[1]==$toHour&&a[2]==$toMin&&a[3]<=$toSec)))print}"
        fi
elif [ $toDay -gt $fromDay ]; then
        echo "{split(\$3, a, \":\");if((\$2==$fromDay&&((a[1]==$fromHour&&a[2]==$fromMin&&a[3]>=$fromSec)||(a[1]==$fromHour&&a[2]>$fromMin)||(a[1]>$fromHour)))||(\$2>$fromDay&&\$2<$toDay)||(\$2==$toDay&&((a[1]<$toHour)||(a[1]==$toHour&&a[2]<$toMin)||(a[1]==$toHour&&a[2]==$toMin&&a[3]<=$toSec))))print}"
fi