2017-05-01 32 views
0

我需要將行分割爲變量。來自Web日誌的Python分割線

這裏是2行的一個示例:

port11.annex1.naples.net [30:00:00:03] "GET /logos/small_gopher.gif HTTP/1.0" 200 935 
port11.annex1.naples.net [30:00:00:03] "GET /icons/book.gif" 200 935 

然而,如可以看到有時行缺少一個整體。

如何分割這個沒有錯誤?

目前我使用:

for x in log.readlines(): 
     data = x.split(" ") 
     hostname = data[0] 
     time = data[1] 
     command = data[2] 
     resource = data[3] 
     version = data[4] 
     status = data[5] 
     size = data[6] 

這給了錯誤,因爲不是每行有7個「項目」

也許我應該使用多個分隔符拆分,但我不能找到一個很好的有效的方法...

+0

因此,如果不是所有5件都存在,你想要代碼做什麼?返回最後一塊?如果是這樣,那麼'data [-1]'將會起作用。 – numbermaniac

+0

數據[-1]將在第一行返回'935',而'200'則是由數據[5]返回的主機名。所以我不認爲他總是想要最後一個項目。 –

+0

Maarten - 你已經發布了2行數據[5]返回你想要的。我認爲對於任何人來回答這個問題,你還需要在數據[5]沒有得到你想要的主機名(例如返回一個錯誤)的地方張貼一行,然後解釋確定主機名在哪裏的規則你的字符串/列表(因爲它並不總是空格分隔的列表中的第五項) –

回答

0

爲什麼你不這樣做?假設你的日誌字符串是這一個:

log = r'port11.annex1.naples.net [30:00:00:03] "GET /icons/book.gif" 200 935' 
data = log.split(" ") 
for i in data: 
    print i 

這樣你就不必爲索引,將能夠去除硬編碼。

0

您可以使用正則表達式來匹配日誌的不同組件。然後,您將檢查請求部分是由命令,資源和版本還是僅包含命令和資源組成。像這樣的東西可以工作:

import re 

# open your log file here... 

logmatcher = re.compile("([^ ]+) (\[[:0-9]+\]) (\"[^\"]+\") ([0-9]+) ([0-9]+)") 

for x in log.readlines(): 
    res = logmatcher.findall(x) 
    if len(res) > 0: 
    hostname = res[0][0] 
    time = res[0][1] 
    req = res[0][2][1:-1].split(" ") #[1:-1] to get rid of the "" 
    if len(req) > 2: # check if request contains the http version 
     command = req[0] 
     resource = req[1] 
     version = req[2] 
    else: 
     command = req[0] 
     resource = req[1] 
     version = "" # there's no version in the request. just use "" 
    status = res[0][3] 
    size = res[0][4]