考虑以下不同大小的文件:
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中存储这么多信息,并以某种方式直接在输出文件中写入行?谢谢!
答案 0 :(得分:3)
在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
答案 1 :(得分:0)
我相信这样的事情就是你想要的。请注意,我不会存储行数组,但在需要时会懒惰地读取行。它有助于节省内存
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
答案 2 :(得分:0)
尝试一次阅读一行。如果我们可以弄清楚如何不短路,或者我们可以通过没有作为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
答案 3 :(得分:0)
我会为奇数行创建一个生成器。然后获取我想要的行并将它们写入文件。这是代码:
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')])
答案 4 :(得分:0)
此脚本处理任意数量的文件并打印每个文件的每一行,直到所有文件都达到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:])