我希望使用我设计的 perl 命令来解析日志。到目前为止,我想要完成的就是提取特定的时间戳格式并检索主机。日志看起来像这样
2016-05-07T09:07:04.933343+00:00 heroku[router]: status=301 bytes=680 service=2698ms connect=1ms dyno=web.2 fwd="10.29.10.29" at=info host="jamaican.com" request_id=32fc8d88-99f8-4cc2-89f9-284d059eebf8 method=GET path="/blog"
我的命令可以解析我想要的日期格式,但我似乎无法弄清楚如何在输出中添加主机。任何建议都会很棒!
cat test.log |
perl -lne 'print $1 if /^([0-9]+[-]+[0-9]+[0-9]+[-]+[0-9]+[0-9]+[T]+[0-9]+[0-9]+[:]+[0-9]+[0-9]+[:]+[0-9]+[0-9])/'
答案1
尝试这个:
perl -nle'($time, $host) = /^(\S+)\s(?:\S+\s+){8}\S+="(\S+?)"/; print "$time $host"'
输出:
2016-05-07T09:07:04.933343+00:00 jamaican.com
\S
表示非空间\s
是空间(?:)
是未捕获的逻辑分组{8}
是跳过的“单词”\S+="(\S+?)"
意思是:跳过直到并捕获两个引号=
之间的内容"
($time, $host) = /.../
将两个捕获的组分配给$time
和$host
答案2
您需要使用第二个捕获组捕获主机名。
例如使用您的示例输入:
$ cat test.log
2016-05-07T09:07:04.933343+00:00 heroku[router]: status=301 bytes=680 service=2698ms connect=1ms dyno=web.2 fwd="10.29.10.29" at=info host="jamaican.com" request_id=32fc8d88-99f8-4cc2-89f9-284d059eebf8 method=GET path="/blog"
这个 perl 单行代码提取时间戳和主机名字段。我也对正则表达式进行了一些改进,用于\d
数字,每个数字都有一个匹配计数。
$ perl -lne 'print "$1 $2" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}) ([^ ]+) /)' test.log
2016-05-07T09:07:04.933343+00:00 heroku[router]:
另一种选择:
$ perl -lne 'print "$1 $2 $3" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}) ([^[]+)\[([^]]+)\]/)' test.log
2016-05-07T09:07:04.933343+00:00 heroku router
我假设您想要本地计算机的主机名(我什至没有注意到host="jamaican.com"
日志条目的部分)。这可能不是您想要的,因此如果您想要 后面双引号内的主机名host=
,那么:
$ perl -lne 'print "$1 $2" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}).*host="([^"]+)"/)' test.log
2016-05-07T09:07:04.933343+00:00 jamaican.com
或者(更简单):
$ perl -lne 'print "$1 $2" if (m/(^\S+).*host="([^"]+)"/)' test.log
2016-05-07T09:07:04.933343+00:00 jamaican.com
或者提取时间戳,使用 解析它Date::Parse
并使用 重新格式化它Date::Format
。
$ perl -MDate::Parse -MDate::Format -lne \
'if (m/(^\S+).*host="([^"]+)"/) {
print join(" ", time2str("%Y-%m-%d %R %z",str2time($1)), $2)
}' test.log
2016-05-07 19:07 +1000 jamaican.com
注意:时间戳已转换为本地时区(对我来说,即 +1000 或澳大利亚东部标准时间)。 time2str()
默认情况下使用本地时区,但您可以给它第三个参数 ( time2str(TEMPLATE, TIME [, ZONE])
) 以使其输出任何其他区域的时间。
$ perl -MDate::Parse -MDate::Format -lne 'if (m/(^\S+).*host="([^"]+)"/) {
print join(" ", time2str("%Y-%m-%d %R %z",str2time($1),"+0"), $2)
}' test.log
2016-05-07 09:07 +0000 jamaican.com