[英]Concatenate every n-th line from multiple large files in python
考慮以下大小不同的文件:
FILE1.TXT
sad
mad
rad
cad
saf
FILE2.TXT
er
ar
ir
lr
gr
cf
file3.txt
1
2
3
4
5
6
7
8
9
我正在尋找一種方法來連接所有文件的第二行,因此所需的輸出文件將是:
sad
er
1
rad
ir
3
saf
gr
5
7
9
我成功使用以下腳本對測試文件進行了管理:
import os
globalList = list()
for file in os.listdir('.'):
if file.endswith('txt'):
with open(file, 'r') as inf:
l = list()
n=0
for i, line in enumerate(inf):
if i == n:
nline=line.strip()
l.append(nline)
n+=2
globalList.append(l)
inf.close()
ouf = open('final.txt', 'w')
for i in range(len(max(globalList, key=len))):
for x in globalList:
if i < len(x):
ouf.write(x[i])
ouf.write('\n')
else:
pass
ouf.close()
上面的腳本適用於小的測試文件。 但是,當我用實際文件(成百上千行的數百個文件)進行嘗試時,我的計算機很快就會耗盡內存,並且腳本崩潰。 有沒有辦法解決這個問題,即避免在RAM中存儲太多信息,而以某種方式直接將行寫入輸出文件中? 謝謝!
在python3中嘗試以下代碼:
from itertools import zip_longest
import glob
every_xth_line = 2
files = [open(filename) for filename in glob.glob("*.txt")]
with open('output.txt', 'w') as f:
trigger = 0
for lines in zip_longest(*files, fillvalue=''):
if not trigger:
for line in lines:
f.write(line)
trigger = (trigger + 1) % every_xth_line
sad
er
1
rad
ir
3
saf
gr
5
7
9
open
本身實際上可以被迭代。 zip_longest
確保腳本將一直運行,直到用完了最長的文件,並且fillvalues只是作為空字符串插入。
必須使用觸發器來分離均勻和不均勻的文件,通過將every_xth_line
設置為其他內容,可以通過簡單的模運算來實現更通用的解決方案。
至於可伸縮性:
我試圖生成大型文件:
cat /usr/share/dict/words > file1.txt
cat /usr/share/dict/words > file2.txt
cat /usr/share/dict/words > file3.txt
粘貼一些副本后:
68M Nov 1 13:45 file.txt
68M Nov 1 13:45 file2.txt
68M Nov 1 13:45 file3.txt
運行它:
time python3 script.py
4.31user 0.14system 0:04.46elapsed 99%CPU (0avgtext+0avgdata 9828maxresident)k
0inputs+206312outputs (0major+1146minor)pagefaults 0swaps
結果:
101M Nov 1 13:46 output.txt
我相信您想要的是這樣的東西。 請注意,我不存儲行數組,而是在需要時懶惰地讀取行。 它有助於節省內存
import os
files = [open(file) for file in os.listdir('.') if file.endswith('txt')]
with open('final.txt', 'w') as f:
while 1:
for file in files:
try:
f.write(next(f))
except StopIteration:
break
if YourCounterFunction:
break
嘗試一次閱讀每一行。 如果我們能弄清楚如何不使短路,或者我們可能沒有得到get_odd的返回
#!/usr/bin/env python3
def get_odd(f):
x = f.readline().strip()
if x: print(x)
return f.readline() or ""
with open("file1.txt", 'r') as x:
with open("file2.txt", 'r') as y:
with open("file3.txt", 'r') as z:
while ("" != (get_odd(x) + get_odd(y) + get_odd(z))):
pass
我將為奇數行創建一個生成器。 然后獲取我想要的行並將其寫入文件。 這是代碼:
def numberLine():
number = -2
while True:
number += 2
yield number
def writeNewFile(files):
with open("newFile.txt", 'w') as theFile:
for line in numberLine():
if files:
for file in files:
try:
with open(file) as openFile:
theFile.write(openFile.readlines()[line])
except IndexError:
files.remove(file)
continue
else:
break
現在,您需要做的就是將帶有文件的列表傳遞到writeNewFile
函數中! writeNewFile([file for file in os.listdir() if file.endswith('txt')])
該腳本處理任意數量的文件,並在每個文件的第二行打印直到所有文件都達到EOF。
#!/usr/bin/env python
import sys
def every_second(files):
fds = [open(f,'r') for f in files]
i = 0
end = 0
num = len(fds)
while end < num:
for fd in fds:
try:
l = fd.readline()
except:
continue
if l == "":
end += 1
fd.close()
elif i%2 == 0:
sys.stdout.write(l)
i += 1
if __name__ == '__main__':
every_second(sys.argv[1:])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.