sed 或 grep 命令提取与特定日期和时间范围匹配的所有行

sed 或 grep 命令提取与特定日期和时间范围匹配的所有行
2022-09-08T08:55:10+02:00             
2022-09-08T19:55:16+02:00            200     200     76  0GET /v1/heartbeat/tcanalytics HTTP/1.1     
2022-09-08T23:55:17+02:00             200     200    POST /v1/accountmanagement             
2022-09-10T20:55:17+02:00        200     200     76  0GET /v1/heartbeat/tcanalytics HTTP/1.1       
2022-09-08T21:55:10+02:00              0.000   -       -      172 0GET /v1/heartbeat/tcanalytics H   
2022-09-10T21:55:17+02:00             200     200     1403643      POST /v1/accountmanagement        
2022-09-10T22:55:17+02:00 

我的文件看起来是这样的。我们需要从这个文件中获取 2022-09-08 以及上午 8 点到 10 点的特定时间范围内的所有内容。我试过这个

'sed -n '/2022-09-08T08:00:26+02:00/,/2022-09-08T11:00:26+02:00/p' logfile

但它不起作用。有人能给我指明正确的方向吗?

答案1

sed不知道时间和日期,所以给它一个时间范围是行不通的。dateutils知道日期,特别是dategrep在这种情况下会很好用,例如:

dategrep '>=2022-09-08T08:00:26+02:00 && <=2022-09-08T11:00:26+02:00' < infile

输出:

2022-09-08T08:55:10+02:00

或者范围更广:

dategrep '>=2022-09-08T08:00:26+02:00 && <=2022-09-08T23:00:26+02:00' < infile

输出:

2022-09-08T08:55:10+02:00
2022-09-08T19:55:16+02:00        200     200     76  0GET /v1/heartbeat/tcanalytics HTTP/1.1
2022-09-08T21:55:10+02:00                        0.000   -       -      172 0GET /v1/heartbeat/tcanalytics H

答案2

这个简单的解决方案假设时间范围以整整一小时开始和结束。

2022-09-08T08:00:00要获取从到 的时间范围2022-09-08T10:59:59,您可以使用

grep '^2022-09-08T08:
^2022-09-08T09:
^2022-09-08T10:' logfile

对于更大的时间范围,列出所有日期和时间会变得不切实际。

问题中的示例输入

2022-09-08T08:55:10+02:00
2022-09-08T19:55:16+02:00            200     200     76  0GET /v1/heartbeat/tcanalytics HTTP/1.1
2022-09-08T23:55:17+02:00             200     200    POST /v1/accountmanagement 
2022-09-10T20:55:17+02:00        200     200     76  0GET /v1/heartbeat/tcanalytics HTTP/1.1
2022-09-08T21:55:10+02:00              0.000   -       -      172 0GET /v1/heartbeat/tcanalytics H
2022-09-10T21:55:17+02:00             200     200     1403643      POST /v1/accountmanagement
2022-09-10T22:55:17+02:00

输出结果为一行

2022-09-08T08:55:10+02:00

答案3

sed操作字符串,它不理解日期的概念。要使你的工作正常进行,文件中必须包含准确/2022-09-08T08:00:26+02:00/,/2022-09-08T11:00:26+02:00/p的字符串。2022-09-08T08:00:26+02:002022-09-08T11:00:26+02:00

我们可以注入它们;然后我们需要按时间戳排序;然后sed应该工作。

幸运的是,您的时间戳logfile采用了可以轻松排序的格式LC_ALL=C sort -k 1,1,只要所有时间戳都以 结尾即可+02:00

start='2022-09-08T08:00:26+02:00'
end='2022-09-08T11:00:26+02:00'

printf '%s\n%s\n' "$start" "$end" \
| LC_ALL=C sort -k 1,1 - logfile \
| sed -n "/$start/,/$end/p"

笔记:

  • 输出将包括$start我们注入的行以及具有此精确时间戳的所有行logfile(不一定按此顺序)。

  • 输出将只包含一行带有$end时间戳的内容。它可能是$end我们注入的行,也可能是带有logfile此精确时间戳的行。其他带有此精确时间戳的行将不会被打印。

  • 如果logfile很大,sort则必须做大量工作。如果文件中的时间戳已排序,则可以避免这种情况;sort -m如果已排序,则使用。通常日志中的时间戳是排序的,但在您的例子中,它们不是

  • printf只会打印出什么$start$end扩展为。在sed扩展的变量中,至少会被解释为正则表达式,但一般来说代码。有问题的时间戳不包含会破坏sed代码或在正则表达式中特殊的字符,因此在这种情况下它应该是安全的。

  • 我认为dategrep来自另一个答案可能是正确的工具。如果可以的话就使用它。我的答案应该是一个更便携(存根)的解决方案。

相关内容