2010-06-22 65 views
1

我有大約4MB的文件(我稱之爲大文件)...這個文件有大約160000行...以特定的格式...我需要定期剪切它們(不是以相等的間隔),即在一個特定的格式結束,並寫入另一個文件的部分..如何加載大文件並將其剪切成更小的文件?

基本上,我想要的是將大文件的信息複製到許多較小的文件...當我讀大文件繼續寫信息到一個文件,並在某種模式發生後,然後結束這一點,並開始寫入該行到另一個文件...

通常,如果它是一個小文件,我想它可以完成不知道我是否可以執行file.readline()讀取每一行檢查模式是否結束如果不是,則將其寫入文件如果模式e ND然後更改文件名打開新file..so上,但如何做到這一點的這個大文件..

在此先感謝..

didnt提到的文件格式,因爲我覺得它不是neccesary意志提及如果需要..

回答

2

我會先讀取所有在內存據稱,大文件作爲行的列表:

with open('socalledbig.txt', 'rt') as f: 
    lines = f.readlines() 

應該多一點4MB - 微小甚至今天的手機標準,電腦更普通。

然後,執行您需要的任何處理來確定您想要寫入較小文件的每組行的開始和結尾(我不確定您的問題的文本中這些組是否可以重疊或留下空白,所以我提供了他們完全被允許的最通用的解決方案 - 這也將覆蓋更多受限的用例,並沒有真正的性能損失,但如果約束非常嚴格,代碼可能會更簡單。

說你把這些數字在列表starts(指數從0第一行寫的,包括在內),ends(指數從第一行的0不寫 - 可以合法和innocuosly是len(lines)以上),names (你想寫的文件名),所有列表當然具有相同的長度。

然後,最後:

assert len(starts) == len(ends) == len(names) 

for s, e, n in zip(starts, ends, names): 
    with open(n, 'wt') as f: 
     f.writelines(lines[s:e]) 

......而這一切,你需要做的!

編輯:所述OP似乎是由具有這些列表的概念混淆,所以讓我嘗試舉一個例子:寫出到文件中的每個塊開始於含有'begin'(包含)的線和結束於包含'end'(也包含在內)的第一個緊接後面的行,並且要寫入的文件的名稱應爲result0.txt,result1.txt等等。 如果「關閉結束」的數量與「開始打開」的數量不同(並且記住,第一個緊接着的「結束」結束所有未決的「開始」)是錯誤的。不允許包含'begin''end'的行。

非常任意設定的條件,可以肯定的,但隨後的OP使我們完全在有關該問題的實際細節黑暗,所以我們還能做,但我想大多數瘋​​狂 - ?)

outfile = 0 
starts = [] 
ends = [] 
names = [] 
for i, line in enumerate(lines): 
    if 'begin' in line: 
    if 'end' in line: 
     raise ValueError('Both begin and end: %r' % line) 
    starts.append(i) 
    names.append('result%d.txt' % outfile) 
    outfile += 1 
    elif 'end' in line: 
    ends.append(i + 1) # remember ends are EXCLUDED, hence the +1 

就是這樣 - 關於具有相同長度的三個列表的assert將負責檢查約束是否受到尊重。

由於約束和規範的更改,因此當然會因此該代碼段的變化 - 只要它填補了三個等長名單startsendsnames,究竟如何這樣做的事項對代碼的其餘部分來說並不重要。

+0

那裏不會在組中重疊寫,但可能不得不在兩者之間留有一條線之間的空白.. 請告訴我們上述代碼中的開始,結尾和名稱是什麼更明確.. – kaki 2010-06-22 16:24:12

+0

@kaki,好吧,我認爲我很清楚,但我會添加一個完全虛假的例子(因爲我們根本不知道細節)試圖進一步幫助你 - 讓我編輯它。 – 2010-06-22 16:38:20

+0

thnq u回覆 – kaki 2010-06-22 17:26:52

0

我不打算進入實際的代碼,但僞代碼會做到這一點。

BIGFILE="filename" 
SMALLFILE="smallfile1" 
while(readline(bigfile)) { 
    write(SMALLFILE, line) 
    if(line matches pattern) { 
     SMALLFILE="smallfile++" 
    } 
} 

這是一個非常糟糕的代碼,但也許你明白了。我也應該說,無論你的文件有多大都無關緊要,因爲你必須閱讀文件。

1

一個4MB的文件非常小,它確實適合內存。最快的方法是將其全部讀取,然後遍歷搜索該模式的每一行,根據模式將該行寫入適當的文件(您的小文件的方法)。

相關問題