我正在尝试解析日志并获取时间戳之间的界限。如下所示的方法,但面临正则表达式的问题
记录模式:
IP - - [20/Apr/2018:14:25:37 +0000] "GET / HTTP/1.1" 301 3936 "-" "
IP - - [20/Apr/2018:14:44:08 +0000]
----------------------------------
IP- - [20/Apr/2018:20:43:46 +0000]
由于日志中还包含其他日期,因此我需要在14:25
和20:43
之间获取第4个月的行。
试过这个:
sed -n '/\[14:25/,/\[20:43/p' *-https_access.log.1
但没有工作。
答案 0 :(得分:1)
由于你提到你想要4月20日的日志,我建议像:
$ sed -n '/20\/Apr\/2018:14:25/,/20\/Apr\/2018:20:43/p' *-https_access.log.1
如果“20:43”发生在其他地方,这种情况与错误匹配的可能性很小。
答案 1 :(得分:0)
要使用sed或awk打印match1
和match2
之间的行,您可以执行以下操作:
sed -n '/match1/,/match2/p' inputfile
awk '/match1/,/match2/' inputfile
您的示例中的 match1
为20/Apr/2018:14:25
,match2
为20/Apr/2018:20:43
。所以这些命令中的任何一个都适合你:
sed -n '/20\/Apr\/2018:14:25/,/20\/Apr\/2018:20:43/p' inputfile
awk '/20\/Apr\/2018:14:25/,/20\/Apr\/2018:20:43/' inputfile
或使用|
作为sed的分隔符以防止转义斜杠:
sed -n '\|20/Apr/2018:14:25|,\|20/Apr/2018:20:43|p' inputfile
答案 2 :(得分:0)
sed不合适,因为它很难比较元素(如日和小时)。
用awk(自评):
awk -F '[ []' '
{
# separt date and hour then rebuild the fields
sub(/:/, " ", $5);$0=$0""
}
# print if it s the day and between the 2 hour (string compare works in this case)
$5 ~ /20.Apr.2018/ && $6 >= "04:25" && $7 < "20:44"
' YourFile
更常见的是,我们可以使用变量将日期和小时作为awk的参数(这里不是目的)
答案 3 :(得分:0)
最佳解决方案是使用awk
。您需要做的是将时间戳转换为unix-time然后进行比较。在awk
中,您可以使用mktime()
mktime(datespec [, utc-flag ])
:将datepec转换为与systime()
返回的格式相同的时间戳。它类似于 ISO C中相同名称的函数。参数,datespec,是一个YYYY MM DD HH MM SS [DST]
形式的字符串。该字符串由 六个或七个数字分别代表全年 包括世纪,月份从1到12,月份从1 到了31,小时从0到23,分钟从0到59, 从0到60,55的秒数和可选的夏令时标志。
要将表单20/Apr/2018:14:25:37 +0000
的时间格式转换为2018 04 20 14 25 37 +0000
awk -v tstart="20/Apr/2018:14:25:00" -v tend = "20/Apr/2018:20:43:00" \
'function tounix(str) {
split(str,a,"/|:| ")
return mktime(a[3]" "month[a[2]]" "a[1]" "a[4]" "a[5]" "a[6])
}
BEGIN{
month["Jan"]="01";month["Feb"]="02";month["Mar"]="03"
month["Apr"]="04";month["May"]="05";month["Jun"]="06"
month["Jul"]="07";month["Aug"]="08";month["Sep"]="09"
month["Oct"]="10";month["Nov"]="11";month["Dec"]="12"
FS="\\[|\\]"
t1=tounix(tstart)
t2=tounix(tend)
}
{ t=tounix($2) }
(t1<=t && t<=t)' <file>
这种方法非常稳健,因为它可以进行真正的时间比较,这与闰年,日/月/年交叉无关......,与提供的其他解决方案相比,此方法也不需要存在tstart
tend
和file