2015-04-07 136 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