我有一个以下形式的脚本:
2017-12-11 10:20:16.993 ...
2017-12-12 10:19:16.993 ...
2017-12-13 10:17:16.993 ...
我想通过 awk - F.
提取第一列,并将其与实际系统时间(以秒为单位)进行比较,如果差异小于 300 秒,则打印该行。
> SYSTEM_TIME=$(date +%s)
> awk -F. -v system_time=$SYSTEM_TIME '{gsub(/[-:]/," ",$1); if(system_time-mktime($1) <= 300) {print $0}}' log.txt
这是我的代码,但我不能使用 mktime,因为它不符合 POSIX 规范。没有它可以完成吗?
谢谢
艾哈迈德
最佳答案
General Remark: logfiles are often incomplete. A date-time format is given, but often the time-zone is missing. When daylight-saving comes into-play it can mess up your complete karma if you are missing your timezone.
注意:在下面的所有命令中,将假定日志文件中的日期采用 UTC 格式,并且系统以 UTC 格式运行。如果情况并非如此,请注意,在夏令时开始时运行以下任何命令时,夏令时都会产生问题。
date
和 awk
的组合:(不是 POSIX)
如果您的 date
命令具有 -d
标志(不是 POSIX),您可以运行以下命令:
awk -v r="(date -d '300 seconds ago' '+%F %T.%3N)" '(r < $0)'
仅限 GNU awk:
如果您想使用mktime
,那么更容易做到:
awk 'BEGIN{s=systime();FS=OFS="."}
{t=$1;gsub(/[-:]/," ",t); t=mktime(t)}
(t-s < 300)' logfile
我将假设将来不会创建日志文件,因此所有时间始终小于系统时间。
POSIX:
如果您无法使用mktime
但只想使用posix,这也意味着date
没有-d
标志,您可以创建自己的 mktime
实现。请注意,此处提供的版本不会像 mktime
那样进行任何时区更正。 mktime_posix
假定 datestring
采用 UTC 格式
awk -v s="$(date +%s)" '
# Algorithm from "Astronomical Algorithms" By J.Meeus
function mktime_posix(datestring, a,t) {
split(datestring,a," ")
if (a[1] < 1970) return -1
if (a[2] <= 2) { a[1]--; a[2]+=12 }
t=int(a[1]/100); t=2-t+int(t/4)
t=int(365.25*a[1]) + int(30.6001*(a[2]+1)) + a[3] + t - 719593
return t*86400 + a[4]*3600 + a[5]*60 + a[6]
}
BEGIN{FS=OFS="."}
{t=$1;gsub(/[-:]/," ",t); t=mktime_posix(t)}
(t-s <= 300)' logfile
相关:this answer , this answer
关于bash - awk 提取列但仅从一行中提取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59932951/