如何加载一个大文件并将其剪切成较小的文件?

时间:2010-06-22 15:29:38

标签: python file

我有大约4MB的文件(我称之为大文件)...这个文件有大约160000行......在特定的格式...我需要定期剪切它们(不是等间隔),即在某种格式的末尾,将该部分写入另一个文件..

基本上,我想要的是将大文件的信息复制到许多较小的文件中...当我读取大文件时,将信息写入一个文件并在某个模式发生之后再结束这个并开始为该行写入另一个文件......

通常情况下,如果它是一个小文件我想它可以完成不知道我是否可以执行file.readline()来读取每一行检查如果没有模式结束然后将其写入文件如果模式结束然后更改文件名打开新文件..然后如何为这个大文件做..

提前感谢..

没有提及文件格式,因为我认为如果需要,它不是必需的..

3 个答案:

答案 0 :(得分:2)

我首先会在内存中读取所有涉嫌大文件的行列表:

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

应该只需要4MB以上 - 即使按今天的手机的标准来说也是如此,更不用说普通的计算机了。

然后,执行您需要的任何处理来确定要写入较小文件的每组行的开头和结尾(我不确定您的问题文本是否这些组可以重叠或留下空白,所以我提供了最通用的解决方案 - 它们完全被允许 - 这也将涵盖更多受限制的用例,没有真正的性能损失,尽管如果约束非常严格,代码可能会更简单。)

假设您将这些数字放在列表starts中(索引从第一行的0开始写入,包括在内),ends(索引从第一行的0到NOT写入 - 可能是合法且无害的是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似乎对这些列表的概念感到困惑,所以让我试着给出一个例子:写入文件的每个块都从包含{{1 (包含)并在包含'begin'(也包括在内)的第一个紧接在后的行结束,并且要写入的文件的名称应为'end'result0.txt,等等上。 如果“收尾结束”的数量与“开始开始”的数量不同(并且记住,第一个紧接在后的“结束”终止所有未决的“开始”),则会出错;);任何行都不允许包含'begin''end'。

当然,这是一个非常随意的条件,但是,然后,OP让我们完全不知道问题的实际细节,那么我们还能做些什么,但最疯狂地猜测? - )

result1.txt

就是这样 - 关于具有相同长度的三个列表的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 将负责检查约束是否得到遵守。

随着约束和规范的更改,当然这段代码也会相应更改 - 只要它填充三个等长列表assertstarts和{{1完全如何,这对其他代码至关重要。

答案 1 :(得分:1)

一个4MB的文件非常小,它确实适合内存。最快的方法是读取所有内容,然后遍历每一行搜索模式,根据模式(小文件的方法)将行写出到相应的文件。

答案 2 :(得分:0)

我不打算进入实际代码,但伪代码会这样做。

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

这是非常糟糕的代码,但也许你明白了。我还应该说,无论你的文件有多大都没关系,因为无论如何你必须阅读文件。