0

我有一些旋转文件,rotatitve 因为我有 5 个文件,它保存了一整天的日志。如果第一个文件已满,则将日志保存在第二个文件中,如果第二个文件已满,则将日志保存在第三个文件中,如果最后一个文件已满,则删除第一个文件的内容并记录日志保存在第一个文件中。一个文件例如:

$cat log1
2013-06-09 08:00  Error1  08x000001  user2
2013-06-09 08:00  Error1  08x000001  user3
2013-06-09 08:01  Error2  08x000002 user4
2013-06-09 08:02  Error3  08x000003  user5     
              .
              . 
              .
2013-06-09 12:22  Error9  08x900009  user5
2013-06-09 12:22  Error8  08x011011  user1

问题是我需要阅读日志,并在一段时间内进行 grep。

例如,我需要 08:00 到 11:00 之间 2013-06-09 的日志。

即带有小时的行:08:00, 08:01, 08:02, 08:03, ..., 11:00 和日期 2013-06-09

使用 grep 我可以查看日期,但我不知道如何提取一系列小时的行。

4

5 回答 5

2

对于您的具体问题,有几个小时:

grep '^2013-06-09 \(08*\|09*\|10*\|11:00\)'

应该做。

于 2013-07-09T20:26:58.937 回答
2

您需要使用 egrep。然后,您可以将其通过管道传回 grep 以获取日期,甚至可以将其作为一个 egrep

$ egrep "0[8-9]:" log
2013-06-09 08:00  Error1  user2
2013-06-09 08:00  Error1  user3
2013-06-09 08:01  Error2  user2
2013-06-09 08:02  Error3  user5
2013-06-09 09:03  Error3  user5

$ egrep "(0[8-9]|1[0-1]):" a
2013-06-09 08:00  Error1  user2
2013-06-09 08:00  Error1  user3
2013-06-09 08:01  Error2  user2
2013-06-09 08:02  Error3  user5
2013-06-09 09:03  Error3  user5
2013-06-09 10:02  Error3  user5
2013-06-09 10:02  Error3  user5
2013-06-09 11:02  Error3  user5
于 2013-07-09T20:28:09.287 回答
2

让我们看看你的日志文件:

2013-06-09 08:00  Error1  user2
2013-06-09 08:00  Error1  user3
2013-06-09 08:01  Error2  user2
2013-06-09 08:02  Error3  user5
2013-06-09 09:03  Error3  user5
2013-06-09 10:02  Error3  user5
2013-06-09 10:02  Error3  user5
2013-06-09 11:02  Error3  user5

如果我们从时间戳中删除格式怎么办?

201306090800  Error1  user2
201306090800  Error1  user3
201306090801  Error2  user2
201306090802  Error3  user5
201306090903  Error3  user5
201306091002  Error3  user5
201306091002  Error3  user5
201306091102  Error3  user5

现在,获取日期和时间范围会容易得多!让我们看看我们能做些什么。

让我们尝试一个测试:

sed -E 's/([[:digit:]]{4})-([[:digit:]]{2})-([[:digit:]]{2}) ([[:digit:]]{2}):([[:digit:]]{2})/\1\2\3\4\5/' $logfile

sed 是一个流编辑器,我正在使用替代命令(即s)。该命令的形式为:

 sed 's/old/new/' $logfile

这将获取 的每一行并替换with$logfile的第一个实例并打印更改的行。oldnew

old不是一串字母,而是一个正则表达式。正则表达式允许我描述我正在寻找的内容。这是一个非常强大的概念。

[[:digit:]]代表我线上的任何数字,意味着{4}必须有四个。这与日期相符。括号是捕获组。基本上,我将日期的每一部分作为一个单独的实体来捕获。

这里有一个更详细的解释:

([[:digit:]]{4}) - Matches the four digit year
-                  Matches the dash after the year
([[:digit:]]{2})   Matches the two digit month
-                  Matches the dash after the month
([[:digit:]]{2})   Matches the two digit day of month
                   Matches the space between the date and time
([[:digit:]]{2})   Matches the two digit hour
:                  Matches the colon separator between the hours and minutes
([[:digit:]]{2})   Matches the minutes

还记得括号吗?我可以替换日期和时间字符串的各个部分来替换整个字符串

\1   Year
\2   Month
\3   Date of Month
\4   Hour
\5   Minute

看看我的 sed 命令,看看你是否能看到这些部分。

我可以使用awk. 现在我已经重新格式化了我的行以删除时间的格式,我可以使用 awk 来分解我的行的三个部分:

 sed -E 's/([[:digit:]]{4})-([[:digit:]]{2})-([[:digit:]]{2}) ([[:digit:]]{2}):([[:digit:]]{2})/\1\2\3\4\5/' $logfile \
 | awk '{
     if ( ( $1 >= 201306090800 ) && ( $1 <= 201306091100 ) ) {
         print $0
     }
}'

好吧,有点粗糙。日期和时间在 awk 程序中是硬编码的,输出将打印出所有格式删除的日期。但是,它会起作用。

需要做更多的工作才能使其平滑。例如,可能让用户输入日期和时间范围,并将日期和时间重新格式化为可识别的形状。但是,会做你想做的事。

如果需要多个日志文件,可以使用catwhich 在这种情况下不是没用的:

cat log* | sed -E 's/([[:digit:]]{4})-([[:digit:]]{2})-([[:digit:]]{2}) ([[:digit:]]{2}):([[:digit:]]{2})/\1\2\3\4\5/' | awk '{

     if ( ( $1 >= 201306090800 ) && ( $1 <= 201306091100 ) ) {
         print $0
     }
}'

主要思想是以您想要的方式向数据发送消息。如果您指定更高级的脚本语言,如 Perl 或 Python,这会更容易。事实上,这正是导致 Larry Wall 发明 Perl 的任务类型。

于 2013-07-09T21:04:47.070 回答
1

如果您的日期格式是yyyy-mm-dd HH:MM,如果我理解正确的话,这相对容易。

你可以:

awk '$1" "$2>="2013-06-09 08:00" && $1" "$2 <= "2013-06-09 11:00"' *.log

将匹配您的*.log所有 5 个日志文件。它可能是不同的模式,例如log.*取决于您的文件名。

于 2013-07-09T20:27:22.647 回答
0

您需要的是一个日志查看器。周围有很多,但我前一段时间使用的是multitail

于 2013-07-09T20:29:45.027 回答