2013-04-01 36 views
0

我對Python非常陌生,我已經在這裏找到了大多數問題的答案,但是這個問題讓我很難過。Python - 在單行/多行文件中讀取文件

我處理使用Python的日誌文件,一般每行以日期/時間戳記,如啓動:

[1/4/13 18:37:37:848 PST] 

99例的%我可以逐行讀取,尋找感興趣的項目和相應地處理它們,但是偶爾在日誌文件中的條目將包括具有回車符/換行符的消息,因爲它將跨越多行。

有沒有一種方法可以輕鬆讀取「時間戳」之間的文件,以便在出現這種情況時多條線會合併到一個讀取中?例如:

[1/4/13 18:37:37:848 PST] A log entry 
[1/4/13 18:37:37:848 PST] Another log entry 
[1/4/13 18:37:37:848 PST] A log entry that somehow 
got some new line 
characters mixed in 
[1/4/13 18:37:37:848 PST] The last log entry 

將被讀作四行而不是六行,因爲它現在是。

在此先感謝您的幫助。

克里斯,

更新....

myTestFile.log包含上面完全​​相同的文字,這裏是我的腳本:

import sys, getopt, os, re 
sourceFolder = 'C:/MaxLogs' 
logFileName = sourceFolder + "/myTestFile.log" 
lines = [] 

def timestamp_split(file): 
    pattern = re.compile("\[(0?[1-9]|[12][0-9]|3[01])(\/)(0?[1-9]|[12][0-9]|3[01])(\/)([0-9]{2})(\)") 
    current = [] 
    for line in file: 
     if not re.match(pattern,line): 
      if current: 
       yield "".join(current) 
      current == [line] 
     else: 
      current.append(line) 
    yield "".join(current) 

print "--- START ----" 
with open(logFileName) as file: 
    for entry in timestamp_split(file): 
     print entry 
     print "- Record Separator -" 
print "--- DONE ----" 

當我運行它,我得到這個:

--- START ---- 
[1/4/13 18:37:37:848 PST] A log entry 
[1/4/13 18:37:37:848 PST] Another log entry 
[1/4/13 18:37:37:848 PST] A log entry that somehow 

- Record Separator - 
[1/4/13 18:37:37:848 PST] A log entry 
[1/4/13 18:37:37:848 PST] Another log entry 
[1/4/13 18:37:37:848 PST] A log entry that somehow 

- Record Separator - 
[1/4/13 18:37:37:848 PST] A log entry 
[1/4/13 18:37:37:848 PST] Another log entry 
[1/4/13 18:37:37:848 PST] A log entry that somehow 
[1/4/13 18:37:37:848 PST] The last log entry 
- Record Separator - 
--- DONE ---- 

我似乎是迭代了太多次,我期待(希望)f或者是這樣的:

--- START ---- 
[1/4/13 18:37:37:848 PST] A log entry 
- Record Separator - 
[1/4/13 18:37:37:848 PST] Another log entry 
- Record Separator - 
[1/4/13 18:37:37:848 PST] A log entry that somehow got some new line characters mixed in 
- Record Separator - 
[1/4/13 18:37:37:848 PST] The last log entry 
- Record Separator - 
--- DONE ---- 

如在我意外地與來自時我測試正則表達式模式的比較離開評價所討論的,如果刪除它,然後我得到的所有其迷惑局部線的我更多!

--- START ---- 
got some new line 
characters mixed in 

- Record Separator - 
got some new line 
characters mixed in 

- Record Separator - 
--- DONE ---- 

回答

2

要做到這一點,最簡單的辦法是實現一個簡單的發電機要做到這一點:

def timestamp_split(file): 
    current = [] 
    for line in file: 
     if line.startswith("["): 
      if current: 
       yield "".join(current) 
      current == [line] 
     else: 
      current.append(line) 
    yield "".join(current) 

當然,這是假定"["在一行的開頭就足以表示一個標記 - 你可能想做一個更重要的檢查。

然後,只需做一些事情,如:(這裏使用the with statement - 一個很好的做法打開文件)

with open("somefile.txt") as file: 
    for entry in timestamp_split(file): 
     ... 

+0

看起來不錯,謝謝,我有一個匹配時間戳的正則表達式,所以我認爲我可以修改上面的代碼來做一個匹配,而不是依靠[ - 我認爲這應該足夠強大,我不認爲我的數據中會出現類似的時間戳。 – Chris

+0

感覺接近...我似乎仍然得到奇怪的結果,有什麼我失蹤? – Chris

+0

@Chris你想檢查模式*是否匹配行的開頭。如果它是**時間戳線,則應該執行「if」塊。 –

0
import re 

lines = [] 
pattern = re.compile('\[\d+/\d+/\d+\s\d+:\d+:\d+\s\w+\]') 
with open('filename.txt', 'r') as f: 
    for line in f: 
     if re.match(pattern, line): 
      lines.append(line) 
     else: 
      lines[-1] += line 

這與正則表達式匹配的時間戳。可以根據需要進行調整。它還假定第一行包含時間戳。

+0

這也預先構建了整個列表,如果這些文件非常大,可能會導致問題。 –

+0

如果您不想介紹整個文件,可以通過在整個文件中使用're.split()'而不是檢查每一行來大大簡化上述過程。 – alexis

+0

與生成器不同,它允許您使用生成的列表執行其他操作,而不是僅僅遍歷它們(除非您再次將生成器轉換爲列表,在這種情況下,您並不需要它),並且它應該比're.split()'快得多,儘管我沒有測試那個部分。像往常一樣,這取決於你在做什麼。 –