【问题标题】:python3 split big file by delimiter into small files (not size, lines)python3通过分隔符将大文件拆分为小文件(不是大小,行)
【发布时间】:2019-03-09 06:36:18
【问题描述】:

这里是新手。最终任务是学习如何获取两个大 yaml 文件并将它们拆分为数百个小文件。我还没有弄清楚如何使用 ID # 作为文件名,所以一次一件事。

首先:将大文件拆分为多个。这是我的测试数据文件 test-file.yml 的一小部分。每个帖子本身都有一个 - 分隔符:

-
    ID: 627
    more_post_meta_data_and_content
-
    ID: 628

这是我的代码不起作用。到目前为止,我不明白为什么:

with open('test-file.yml', 'r') as myfile:
    start = 0
    cntr = 1
    holding = ''
    for i in myfile.read().split('\n'):
        if (i == '-\n'):
            if start==1:
                with open(str(cntr) + '.md','w') as opfile:
                    opfile.write(op)
                    opfile.close()
                    holding=''
                    cntr += 1
            else:
                start=1
        else:
            if holding =='':
                holding = i
            else:
                holding = holding + '\n' + i
    myfile.close()

欢迎所有提示、建议、指点。谢谢。

【问题讨论】:

  • 由于文件被 '\n' 分割,我会说 'i=='-\n' 不应该工作。

标签: python python-3.x split


【解决方案1】:

如果输入文件很大,则将整个文件读入内存然后分割内存区域是非常低效的。试试这个:

with open('test-file.yml', 'r') as myfile:
    opfile = None
    cntr = 1
    for line in myfile:
        if line == '-\n':
            if opfile is not None:
                opfile.close()
            opfile = open('{0}.md'.format(cntr),'w')
            cntr += 1
        opfile.write(line)
    opfile.close()

还要注意,您不会在close 上下文管理器中打开您在with 中打开的东西;上下文管理器的真正目的就是为您解决这个问题。

【讨论】:

  • 谢谢大家。这是一个很棒的学习时刻,哦​​,忘了把最初的操作定义放在开头。 @tripleee 第 8 行中的 {0} 占位符是什么?
  • 它被format 使用并被第一个参数替换。等效地open('%s.md' % cntr) 使用旧式格式字符串,或open(f'{cntr}.md') 使用现代f 字符串。这一切都在 Python 101 材料中。
【解决方案2】:

作为一个新手,乍一看,您试图将一个未声明的变量 op 写入您的输出。您几乎是正确的,只需要遍历您的 opfile 并写入内容:

    with open('test-file.yml', 'r') as myfile:
        start = 0
        cntr = 1
        holding = ''
        for i in myfile.read().split('\n'):
            if (i == '-\n'):
                if start==1:
                    with open(str(cntr) + '.md','w') as opfile:
                        for line in opfile:
                            op = line
                            opfile.write(op)
                            opfile.close()
                            holding=''
                            cntr += 1
                else:
                    start=1
            else:
                if holding =='':
                    holding = i
                else:
                    holding = holding + '\n' + i
        myfile.close()

希望这会有所帮助!

【讨论】:

    【解决方案3】:

    当您在with context 中处理打开的文件时,with 会在您退出此块时自动为您关闭它。所以你在任何地方都不需要file.close()

    有一个名为readlines 的函数会输出一个生成器,该生成器从打开的文件中一次读取一行。这将比read() 后跟split() 更有效。想想看。您正在内存中加载一个巨大的文件,然后要求 CPU 按\n 字符分割该巨大的文本。效率不是很高。

    你写了opfile.write(op)。这个op 在哪里定义?你不想在holding中写你定义的内容吗?

    试试下面的。

    with open('test.data', 'r') as myfile:
        counter = 1
        content = ""
        start = True
    
        for line in myfile.readlines():
            if line == "-\n" and not start:
                with open(str(counter) + '.md', 'w') as opfile:
                    opfile.write(content)
    
                content = ""
                counter += 1
            else:
                if not start:
                    content += line
    
            start = False
    
        # write the last file if test-file.yml doesn't end with a dash
        if content != "":
            with open(str(counter) + '.md', 'w') as opfile:
                opfile.write(content)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-05
      • 1970-01-01
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多