我正在尝试解析日志并在时间戳记之间获得线条。the sed方法如下,但面对regex
的问题日志模式:
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]
我需要在4月20日的14:25
和20:43
之间获得界限,因为日志还包含其他日期。
尝试了以下方法:
sed -n '/[14:25/,/[20:43/p' *-https_access.log.1
但不工作。
由于您提到了4月20日的日志,我建议这样的东西:
$ sed -n '/20/Apr/2018:14:25/,/20/Apr/2018:20:43/p' *-https_access.log.1
在其他地方发生" 20:43"的情况下,这与虚假匹配相冲突的可能性很小。
sed不合适,因为它很难比较元素(如日和小时(。
带有尴尬(自我评论(:
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
更笼统,我们可以使用变量将日期和小时作为尴尬的参数(不是此处的目的(
用SED或尴尬在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
最好的解决方案是为此使用awk
。您需要做的是将您的时间戳记转换为UNIX时间,然后进行比较。在awk
中,您可以使用mktime()
mktime(datespec [, utc-flag ])
:将datespec变成与systime()
返回的相同形式的时间戳。它类似于 ISOC中同名的函数。参数datespec是一个 形式YYYY MM DD HH MM SS [DST]
的字符串。字符串由 全年分别代表六个或七个数字 包括世纪,一个月从1到12个月,一个月的那一天。 至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>
这种方法很强file
中的日期tstart
和tend