2015-04-07 122 views
-1

我正在写一个脚本来读取日志文件,并从每行中提取3个字符串(提供它们匹配),然后打印到外部文件,可能CSV或类似的。grep为多行字符串,但只打印字符串,而不是整行

每个日志行的格式在组合Apache访问输出,因为这样的:

%D %v %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" 

实施例是:

1550606 *user1.testdomain.com* 100.100.100.100 - - *[07/Apr/2015:09:12:48 +0000]* "GET /TestURI HTTP/1.1" 200 11917 "-" *"Test User Agent"* 

3串我希望提取属于该虚拟主机( %v),时间戳(%t)和用户代理(%{User-Agent} i)

我试过grep和sed的各种组合,但无法弄清楚我是如何得到它只拉我想要的字符串,连接输出,然后打印到文件。

实现此目标的最佳实践是什么?

+0

是你的问题相匹配的格式,只返回行的相关部分,还是串联?或者,您是否遇到问题的所有组成部分? – borrible

+0

发布预期的输出格式。同样,它在Apache中为什么你不用它来写这种格式的另一个日志? – 2015-04-07 10:01:34

+0

格式应输出如:resource.domain.com [17/Apr/2015:00:00:00 +0000]“GET/testurl/blah”“Mozilla Firefox” – lbrookes

回答

0

在你的日志中,%v可以很容易地在每个字符串中的第二个字匹配的,你可以把下面的模式肯定:

^\S+\s(\S+) 

为您提供虚拟主机作为捕获的第一组。时间戳被括在方括号内,因此它可以与以下内容匹配:

\[([^\]]+)\] 

只留下要匹配的用户代理字符串。用户代理是日志中的最后一个字符串,用双引号括起来;使用$占位符:

"([^"]+)"$ 

现在,结合在第3个子模式:

^\S+\s(\S+).*?\[([^\]]+)\].*"([^"]+)"$ 
+0

这应该是哪种正则表达式?或者你的意思是'\ S'和'\ s'而不是'%S'和'%s'? (在这种情况下,提到您使用Perl兼容的正则表达式仍然有意义。) – tripleee

+0

@tripleee啊,[lua模式](http://www.lua.org/manual/5.2/manual.html#6.4.1 ) – hjpotter92