如何使用正则表达式在两个时间帧之间检索日志?

时间:2013-09-03 18:34:24

标签: regex linux bash unix

我有一个巨大的日志文件,其中每一行都是一个日志条目,它有自己的时间戳。如何检索两个指定时间段之间的日志(即开始时间 - 22:00:00,结束时间 - 23:00:00)?

1 个答案:

答案 0 :(得分:2)

使用bash,可以仅基于两个输入时间戳生成正则表达式语句,您可以将其输出到命令(例如grep):

#!/bin/bash

#This is a bare-bone recursive script that accepts input of a start/end timeframe
#in the 24-hour format, based on which a regex statement will be generated that will 
#select all values in between those two timeframes. Please note that this script
#has undergone some optimization (I apologize for the reading difficulty, but it
#did not occur to me until now that someone might have a use for such a script).

#You are free to use, distribute, or modify this script to your heart's content. Any
#constructive feedback is welcome. I did my best to eliminate all bugs, but should
#you find any case where the generated regex is INCORRECT for some timestamps, please
#let me know.

echo $0 - Args passed: $1 $2

START_TIME=$(echo $1 | tr -d ":")
END_TIME=$(echo $2 | tr -d ":")
DIFF_CHAR=""
REGEX=""

function loop ()
{
  diffcharValue=$1
  maxVal=$2
  while [ $diffcharValue -lt $maxVal ]
  do
    REGEX="${REGEX}:[0-5][0-9]"
    let diffcharValue+=2
  done
}

function regexGen ()
{
  diffChar=$1
  start=$2
  end=$3
  if [ $diffChar -le 6 ]; then
    regexGen $(($diffChar + 1)) $start $end 0 #the fourth arg acts as a recursion indicaton, whether the function was called recursively or not
    let diffChar-=1
    diffCharMinusOne=$(($diffChar - 1))
    startBegin=${start:0:$diffCharMinusOne}
    endBegin=${end:0:$diffCharMinusOne}
    startCut=${start:$diffCharMinusOne:1}
    endCut=${end:$diffCharMinusOne:1}
    endStartDiff=$(($endCut-$startCut))

    if [ $(($diffChar % 2)) -eq 0 ]; then
      if [ $4 -eq 0 ]; then
        REGEX="${REGEX}$startBegin[$startCut-9]"
        loop $diffChar 6
        REGEX="${REGEX}|$endBegin[0-$endCut]"
        loop $diffChar 6
        REGEX="${REGEX}|"
      elif [ $endStartDiff -gt 1 ]; then
        if [ $endStartDiff -eq 2 ]; then
          REGEX="${REGEX}$startBegin[$(($startCut+1))]"
        else
          REGEX="${REGEX}$startBegin[$(($startCut+1))-$(($endCut-1))]"
        fi
        loop $diffChar 6
        echo $REGEX
      else
        echo ${REGEX%?}
      fi
    else
      if [ $4 -eq 0 ]; then
        if [ $startCut -lt 5 ]; then
          REGEX="${REGEX}$startBegin[$startCut-5][0-9]"
          loop $diffChar 5
          REGEX="${REGEX}|"
        fi
        if [ $endCut -gt 0 ]; then
          REGEX="${REGEX}$endBegin[0-$endCut][0-9]"
          loop $diffChar 5
          REGEX="${REGEX}|"
        fi
      elif [ $endStartDiff -gt 1 ]; then
        if [ $diffCharMinusOne -gt 0 ]; then
          REGEX="${REGEX}$startBegin"
        fi
        if [ $endStartDiff -eq 2 ]; then
          REGEX="${REGEX}[$(($startCut+1))][0-9]"
        else
          REGEX="${REGEX}[$(($startCut+1))-$(($endCut-1))][0-9]"
        fi
        loop $diffChar 5
        echo $REGEX
      else
        echo ${REGEX%?}
      fi
    fi
  fi
}

for a in {0..5}
do
  if [ ${END_TIME:$a:1} -gt ${START_TIME:$a:1} ];then
    DIFF_CHAR=$(($a+1))
    break
  fi
done

result=$(regexGen $DIFF_CHAR $START_TIME $END_TIME 1 | sed 's/\([0-9][0-9]\)/\1:/g')
echo $result