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:00
2022-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
来自另一个答案可能是正确的工具。如果可以的话就使用它。我的答案应该是一个更便携(存根)的解决方案。