【问题标题】:Split file after X lines at blank line在空白行的 X 行之后拆分文件
【发布时间】:2017-07-20 00:53:37
【问题描述】:

我需要将大文本文件拆分成更小的块,其中文本文件包含需要保持在一起的数据。每个相关的数据块都通过换行符与下一个数据块分开,如下所示:

Some Data belonnging to chunk 1
Some Data belonnging to chunk 1
Some Data belonnging to chunk 1

More Data, belonnging to chunk 2
More Data, belonnging to chunk 2
More Data, belonnging to chunk 2

如何定义多行,然后在下一个空白行以维护数据块,拆分文件?我想为此使用 Python,但我不知道在 X 行之后使用拆分函数。

【问题讨论】:

标签: python


【解决方案1】:
from itertools import groupby

with open(myfile, 'r') as f:
    chunks = [[x.strip() for x in v] for k, v in 
              groupby(f, lambda x: x.strip()) if k]

【讨论】:

  • 删除f.readlines() 让文件行上的迭代器工作。不要一次读取整个文件。否则很好的解决方案。
  • 感谢您的提示。我不知道你可以迭代这样的文件。
【解决方案2】:

如果你想为每个块编写新的 chunk1.txt ... chunkN.txt,你可以这样写:

def chunk_file(name, lines_per_chunk, chunks_per_file):

    def write_chunk(chunk_no, chunk):
        with open("chunk{}.txt".format(chunk_no), "w") as outfile:
            outfile.write("".join(i for i in chunk))

    count, chunk_no, chunk_count, chunk = 1, 1, 0, []
    with open(name, "r") as f:
        for row in f:
            if count > lines_per_chunk and row == "\n":
                chunk_count += 1
                count = 1
                chunk.append("\n")
                if chunk_count == chunks_per_file:
                    write_chunk(chunk_no, chunk)
                    chunk = []
                    chunk_count = 0
                    chunk_no += 1
            else:
                count += 1
                chunk.append(row)
    if chunk:
        write_chunk(chunk_no, chunk)

chunk_file("test.txt", 3, 1)

您必须指定属于一个块的行,然后预期换行。

假设你想分块这个文件:

Some Data belonnging to chunk 1

Some Data belonnging to chunk 1
Some Data belonnging to chunk 1
Some Data belonnging to chunk 1
Some Data belonnging to chunk 1
Some Data belonnging to chunk 1

More Data, belonnging to chunk 2
More Data, belonnging to chunk 2
More Data, belonnging to chunk 2

第一个块的行数与第二个块有很大的不同。 (7 行对 3 行)

此示例的输出将是 chunk1.txt

Some Data belonnging to chunk 1

Some Data belonnging to chunk 1
Some Data belonnging to chunk 1
Some Data belonnging to chunk 1
Some Data belonnging to chunk 1
Some Data belonnging to chunk 1

还有chunk2.txt

More Data, belonnging to chunk 2
More Data, belonnging to chunk 2
More Data, belonnging to chunk 2

这种方法假定lines_per_chunk 是最小块大小,因此即使块具有不同的行数,它也可以工作。当达到最小块大小时,我们只寻找一个空白行来结束块。 在上面的例子中,第 2 行有一个空行是没有问题的,因为还没有达到最小块大小。如果第 4 行出现空行,之后块数据继续,就会出现问题,因为指定的标准(行号和空行)不能单独识别块。

【讨论】:

  • 这不适用于大文件(>100 万行)和行数差异很大的块(可能从 8 到 70 行),对吗?
  • @kbecker87 我刚刚修改了解决方案,只在对包含 100 万行的文件进行评估和测试脚本时才准备好行。分块大约需要 8 秒。如果块的大小差异很大,它也可以工作。在您的示例中,您必须将最小大小设置为 8 行才能识别第一个块。如果在 70 行的块中,前 8 行之后没有空行,它会起作用。否则,您需要另一个标准来识别块。
  • 这适用于将文件拆分为每个块的单个文件。实际上,我需要将 1000 个块放入一个文件中,接下来的 1000 个放入下一个,依此类推。
  • @kbecker87 我编辑了答案以允许额外的参数 chunks_per_file,它使您能够选择一个文件中有多少块。
  • 完美!我试图在块之间保留空白行,但什至无法弄清楚?
猜你喜欢
  • 1970-01-01
  • 2016-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-17
相关资源
最近更新 更多