【问题标题】:RegExp to match date and time from custom log file正则表达式匹配自定义日志文件中的日期和时间
【发布时间】:2012-11-07 01:51:06
【问题描述】:

我正在编写一个脚本,为了实现卓越,必须将日期和时间格式从日志文件转换为时间戳。我想要这个以便稍后进行比较。

我的日志文件格式为:

2012-11-06 10:32:45
<log message follows here on multiple lines in XML format> 

我正在使用以下 gawk 表达式将我的日期/时间转换为时间戳:

$ gawk '/^([0-9]{2,4}-?){3} ([0-9]{2}\:?){3}/{print $0;gsub(/\:/," ");print mktime($0)}' logfile.txt

输出将是:

2012-11-01 15:27:28
1293719248

这实际上是我正在寻找的,但问题是正则表达式是否正确?由于我远离正则表达式大师,我也想知道这是否可以。当涉及到正则表达式时,这可以以一种更漂亮的方式完成吗?日志文件中使用的格式永远不会改变,因为我没有费心进行通用日期/时间匹配。也许我表达中的其他东西是fubar? :-)

【问题讨论】:

    标签: regex awk gawk


    【解决方案1】:

    要匹配的 ERE:

    2012-11-06 10:32:45
    

    在它自己的一行是:

    ^[[:digit:]]{4}(-[[:digit:]]{2}){2} [[:digit:]]{2}(:[[:digit:]]{2}){2}$
    

    但你可能会逃脱:

    ^[[:digit:]]([[:digit:]: -][[:digit:]]{2}){6}$
    

    没有得到任何错误的匹配。

    【讨论】:

    • +1 - 这是完全正确的。请注意,大多数正则表达式实现都允许您使用 \d 作为 [:digit:] 的简写。
    【解决方案2】:

    如果您只处理您的日志文件,则正则表达式是可以的。因为您可以假设您的日志文件将始终提供有效的日期时间字符串。 (例如2012-13-56 28:23:77 不会发生)

    但我要指出的是,您的 awk 代码可能有问题。

    • 我不知道您使用的是哪个 gawk 版本(我猜 > 4.0),如果版本 --re-interval 选项不是默认选项。

    • 您的字符串替换出现错误:您也应该将“-”替换为“”,对吗?

    awk 手册页:

     mktime(datespec)
                     Turns datespec into a time stamp of the same form as returned by systime().  The datespec is a string of the form YYYY MM DD HH  MM  SS[  DST].
    

    看看区别:

    kent$  gawk '{print $0;gsub(/:|-/," ");print mktime($0)}' <<<"2012-11-01 15:27:28"
    2012-11-01 15:27:28
    1351780048
    
    output with your awk line:
    2012-11-01 15:27:28
    1293719248
    

    【讨论】:

    • 是的,我使用的是 4.0.1。啊哈,好点(而且很有趣)!由于我的输入生成了一个时间戳而不是 -1,我认为它正确地吞下了包括 - 在内的日期部分。我阅读了手册页,但又懒惰又愚蠢,并忽略了 - 基于前面的声明。 :) 谢谢。
    【解决方案3】:

    可以完全取消正则表达式并简单地测试mktime() 的失败。显然,这取决于您的数据是否可以包含具有日期/时间外观的行。但是,您可能没有考虑过这样做:

    awk '{ line = $0; gsub(/[:-]/, " "); time = mktime($0) } time != "-1" { print line ORS time }' file.txt
    

    结果:

    2012-11-06 10:32:45
    1352161965
    

    来自手册页:

    If datespec does not contain enough elements or if the resulting time is out of 
    range, mktime() returns −1.
    

    【讨论】:

    • 这很聪明,我会为此 +1,因为它显示了解决问题的不同方法。出于好奇,这样做会对性能产生更大的影响吗?
    • @Qben:在我的测试中,这实际上比您描述的正则表达式方法更快(即使我考虑 Kent 的答案并将您的两个打印语句减少到只有一个)。这种方法仍然只需要你的时间的三分之二。有趣的嘿。
    • 这确实很有趣。我猜写 mktime() 的人比我有更好/更优化的正则表达式。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    • 2019-02-26
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多