【问题标题】:Search logs within date/time range在日期/时间范围内搜索日志
【发布时间】:2018-08-25 01:09:55
【问题描述】:

我,新手,已经在这个论坛上下搜索过,并尝试了几种 awks、seds 和 grep。

我正在尝试搜索日志文件以输出日期和时间内的所有日志。

很遗憾,我正在搜索的所有日志都有不同的日期格式。

我确实让这个工作了:

awk '$0 >= "2018-08-23.11:00:00" && $0 <= "2018-08-23.14:00:00"' catalina.out

针对特定的日期格式。

我无法让这些日期格式正常工作,也许是间距问题?

2018-08-23 11:00:00,或 2018 年 8 月 23 日 11:00:00

一些我尝试过的示例:

sed -n '/2018-08-23 16:00/,/2018-08-23 18:00/p' testfile.txt
sed -n '/Feb 23 13:55/,/Feb 23 14:00/p' testfile.txt
awk '$0 >= "2018-08-23 17:00:00" && $0 <= "2018-08-23 19:00:00"' testfile.txt

我也尝试过设置变量: FROM="2018 年 8 月 23 日 17:00:00" , TO="2018 年 8 月 23 日 19:00:00"

awk '$0 >= "$FROM" && $0 <= "$TO"' testfile.txt

谁能帮我解决这个问题?

更新:我让这个适用于 2018-08-23 11:00:00 格式

grep -n '2018-08-23 11:[0-9][0-9]' testfile.txt | head -1
grep -n '2018-08-23 12:[0-9][0-9]' testfile.txt | tail -1
awk 'NR>=2 && NR<=4' testfile.txt > rangeoftext

但我无法让它与 2018 年 8 月 23 日 11:00:00 一起使用 -- 再说一次,我认为这可能是空间问题?不知道怎么解决....

【问题讨论】:

  • grep 用于执行g/re/p 和sed 用于执行s/old/new/。这些都不是你想要做的,所以你甚至不应该考虑grep 或sed。对于所有其他文本操作,例如你描述的问题,你应该使用awk。如果您发布包含简洁、可测试样本输入和预期输出的 minimal reproducible example,那么我们可以为您提供帮助。如果不清楚,请参阅How to Ask。
  • 不是您问题的答案,但您应该查看 Splunk。它是处理日志的最佳工具之一。它采用大多数日期格式,您可以很好地掌握。

标签: awk sed grep


【解决方案1】:

这是一个难题。 grep 和 sed 没有日期的概念,甚至 GNU awk 对日期和时间的支持也很有限。

如果您使用合理的日期格式,即可以在字符串比较中使用的日期格式,例如2018-08-15 17:00:00,问题会变得更容易处理。无论字符串是否包含空格,这都应该有效。但是,请注意自动拆分空格的工具,例如 shell 和 awk。

现在,举个例子:

sed -n '/2018-08-23 16:00/,/2018-08-23 18:00/p' testfile.txt
sed -n '/Feb 23 13:55/,/Feb 23 14:00/p' testfile.txt
awk '$0 >= "2018-08-23 17:00:00" && $0 <= "2018-08-23 19:00:00"' testfile.txt

前两个应该有效,但前提是文件确实包含两个时间戳,因为您只是检查某些任意字符串的存在。第三个也应该可以工作,前提是所有记录都以时间戳开头。

【讨论】:

  • 谢谢,这是我找到的最简单且有效的答案之一
【解决方案2】:

这可能就是您要查找的内容(对您的输入文件的外观做出一些假设):

$ cat file
Aug 22, 2018 11:00:00 bad
2018-08-23 11:00:00 good
Aug 23, 2018 11:00:00 good
2018-08-24 11:00:00 bad

$ cat tst.awk
BEGIN {
    min = raw2dt(min)
    max = raw2dt(max)
}
{ cur = raw2dt($0) }
(cur >= min) && (cur <= max)

function raw2dt(raw,    tmp, mthNr, dt, fmt) {
    fmt = "%04d%02d%02d%02d%02d%02d"
    if ( match(raw,/[0-9]{4}(-[0-9]{2}){2}( [0-9:]+)?/) ) {
        split(substr(raw,RSTART,RLENGTH),tmp,/[^[:alnum:]]+/)
        dt = sprintf(fmt, tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6])
    }
    else if ( match(raw,/[[:alpha:]]{3} [0-9]{2}, [0-9]{4}( [0-9:]+)?/) ) {
        split(substr(raw,RSTART,RLENGTH),tmp,/[^[:alnum:]]+/)
        mthNr = (index("JanFebMarAprMayJunJulAugSepOctNovDec",tmp[1])+2)/3
        dt = sprintf(fmt, tmp[3], mthNr, tmp[2], tmp[4], tmp[5], tmp[6])
    }
    return dt
}

$ awk -v min='Aug 23, 2018 11:00' -v max='2018-08-23 11:00' -f tst.awk file
2018-08-23 11:00:00 good
Aug 23, 2018 11:00:00 good

以上内容适用于任何 UNIX 机器上的任何 shell 中的任何 POSIX awk。

【讨论】:

    【解决方案3】:

    当试图获取一组出现在两个日期之间的日志条目时,永远不应该使用sed 来检查这一点。是的,sed 确实有一个很酷且非常有用的功能来检查地址范围(顺便说一句,awk 也是如此。)但是

    sed -n `/date1/,/date2/p` file
    

    并不总是有效。这意味着它只有在 date1 和 date2 实际上在文件中时才有效。如果缺少其中一个,这将失败。

    具有两个地址的编辑命令应选择从与第一个地址匹配的第一个模式空间到与第二个地址匹配的下一个模式空间的包含范围。

    [address[,address]]
    

    最重要的是,在比较日期时,除非您使用一种健全的格式,否则绝不应该使用字符串比较。一些健全的格式是YYYY-MM-DD,YYYY-MM-DD hh:mm:ss,......一些不好的格式是“2018 年 8 月 1 日”,因为它出现在“2018 年 1 月 1 日”之前,而“99-01-31”出现在“01-01-31”之后,或“2018-2-1”出现在“2018-11-1”之后

    因此,如果可以,请尝试将获得的日期转换为合理的格式。最明智的格式是计算一个纪元的日期差异。 Unix 有各种工具可以计算自 1970-01-01 00:00:00 UTC 的 UNIX EPOCH 以来的秒数。这才是你真正追求的。

    正如您所提到的,您的日志文件具有各种日期格式,这并不容易。尽管 gnu awk 有各种 Time Functions,但它们要求您事先知道格式。

    由于我们不知道您的日志文件中存在哪些格式,我们将使用 unix 函数date,它有一个非常精细的解释器,可以识别很多格式。

    另外,我会假设在awk 中,您能够以某种方式将日期存储在名为date 的字符串中唯一标识日期。也许在日期之后总是出现一个特殊字符,可以让你这样做:

    示例输入文件:

    2018-08-23 16:00 | some entry
    Aug 23 2018 16:01:01 | some other entry
    

    所以,在这种情况下,我们可以说:

    awk -F| -v t1=$(date -d "START_DATE" "+%s") \
            -v t2=$(date -d "END_DATE" "+%s")   \
            '{date=$1}
             {cmd="date -d \""$1"\" +%s"; cmd | getline epoch; close cmd}
             (t1 <= epoch && epoch <= t2)' testfile
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-17
      • 2017-10-25
      • 1970-01-01
      • 1970-01-01
      • 2019-11-05
      • 2019-02-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多