【问题标题】:Combine every number of files in a folder into one file将文件夹中的所有文件合并为一个文件
【发布时间】:2018-08-17 05:01:37
【问题描述】:

我在一个文件夹中有大量文件(大约 200 万个文件),我想将每 50 个文件合并为一个。下面的代码将所有内容合二为一。我无法想出一种方法将每 50 个文件合并为一个文件,并确保任何超过 50 的数字也合并为一个文件。例如,如果文件数为 2,000,034,那么我最终会得到许多文件,其中包含 50 个组合文件,一个文件包含最后 34 个文件。

from glob import iglob
import shutil
import os

PATH = r'C:\Test'

destination = open('allcontents.sh', 'wb')
for file in iglob(os.path.join(PATH, '*.sh')):
    shutil.copyfileobj(open(file, 'rb'), destination)
destination.close()

【问题讨论】:

    标签: python shutil os.path


    【解决方案1】:

    我会使用列表而不是迭代器,因为列表更容易操作:

    filelist = glob(os.path.join(PATH, '*.sh'))
    

    将列表切成 50 项切片并将每个切片中的文件复制到一个文件中。输出文件的名称包含切片中第一个文件的编号:

    BLOCK = 50
    for i in range(0, len(filelist) + BLOCK, BLOCK):
        with open('contents-{}.sh'.format(i), 'wb') as destination:
            for filename in filelist[i:i+BLOCK]:
                with open(filename, 'rb') as infile:
                    shutil.copyfileobj(infile, destination)
    

    【讨论】:

      【解决方案2】:

      你几乎拥有这个。我没有测试过下面的代码,但它会给你一个想法:

      from glob import iglob
      import shutil
      import os
      
      PATH = r'C:\Test'
      
      filecounter = 1
      fiftycounter = 0
      destination = open('fifties1.sh', 'wb')
      for file in iglob(os.path.join(PATH, '*.sh')):
          shutil.copyfileobj(open(file, 'rb'), destination)
          fiftycounter += 1
          if 50 == fiftycounter:
              fiftycounter = 0
              destination.close()
              filecounter += 1
              destination = open('fifties' + str(filecounter) + '.sh', 'wb')
      destination.close()
      

      【讨论】:

        【解决方案3】:

        标准库文档中的itertools recipes 包含此配方(逐字引用):

        from itertools import zip_longest
        def grouper(iterable, n, fillvalue=None):
            "Collect data into fixed-length chunks or blocks"
            # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
            args = [iter(iterable)] * n
            return zip_longest(*args, fillvalue=fillvalue)
        

        您可以使用它来包装您的 iglob() 调用以带回 50 个元素的块(最后一个将在末尾有额外的 None),然后遍历该列表。

        i_files = iglob(os.path.join(PATH, '*.sh'))
        i_grouped = grouper(i_files, 50)
        for (n, group) in enumerate(i_grouped):
          destination_fn = 'allcontents_{}.sh'.format(n)
          with open(destination_fn, 'w') as f:
            for input_fn in group:
              ...
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多