如何在两个时间戳之间使用bash(grep/sed/etc)来获取日志文件的一部分?

Bre*_*nt 3 bash parsing timestamp logfiles

我有一组邮件日志:mail.log mail.log.0 mail.log.1.gz mail.log.2.gz

这些文件中的每一个都包含按时间顺序排序的行,这些行以时间戳开头,如:

5月3日13:21:12 ......

如何使用bash(以及相关的命令行工具)在特定日期/时间之后和另一个日期/时间之前轻松获取每个日志条目,而无需比较每一行?请记住,我的前后日期可能与日志文件中的任何条目都不完全匹配.

在我看来,我需要确定第一行的偏移量大于起始时间戳,并且最后一行的偏移量小于结束时间戳,并以某种方式切出该部分.

Dyl*_*lan 5

将您的最小/最大日期转换为"自纪元以来的秒数",

MIN=`date --date="$1" +%s`
MAX=`date --date="$2" +%s`
Run Code Online (Sandbox Code Playgroud)

n每个日志行中的第一个单词转换为相同的,

L_DATE=`echo $LINE | awk '{print $1 $2 ... $n}'`
L_DATE=`date --date="$L_DATE" +%s`
Run Code Online (Sandbox Code Playgroud)

比较并扔掉线直到你到达MIN,

if (( $MIN > $L_DATE )) ; then continue ; fi
Run Code Online (Sandbox Code Playgroud)

比较并打印线条,直至到达MAX,

if (( $L_DATE <= $MAX )) ; then echo $LINE ; fi
Run Code Online (Sandbox Code Playgroud)

超过时退出MAX.

if (( $L_DATE > $MAX )) ; then exit 0 ; fi
Run Code Online (Sandbox Code Playgroud)

整个脚本minmaxlog.sh看起来像这样,

#!/usr/bin/env bash

MIN=`date --date="$1" +%s`
MAX=`date --date="$2" +%s`

while true ; do
    read LINE
    if [ "$LINE" = "" ] ; then break ; fi

    L_DATE=`echo $LINE | awk '{print $1 " " $2 " " $3 " " $4}'`
    L_DATE=`date --date="$L_DATE" +%s`

    if (( $MIN > $L_DATE  )) ; then continue ; fi
    if (( $L_DATE <= $MAX )) ; then echo $LINE ; fi
    if (( $L_DATE >  $MAX )) ; then break ; fi
done
Run Code Online (Sandbox Code Playgroud)

我在这个文件minmaxlog.input上运行它,

May 5 12:23:45 2009 first line
May 6 12:23:45 2009 second line
May 7 12:23:45 2009 third line
May 9 12:23:45 2009 fourth line
June 1 12:23:45 2009 fifth line
June 3 12:23:45 2009 sixth line
Run Code Online (Sandbox Code Playgroud)

像这样,

./minmaxlog.sh "May 6" "May 8" < minmaxlog.input
Run Code Online (Sandbox Code Playgroud)