3

我有一个包含几千个文件的目录。我希望能够在较大的导演中创建子目录,并将 150 个文件(按扩展名过滤)移动到每个新创建的目录中。我希望得到一些指导来帮助我前进。这是我开始的小事:

wd = os.chdir(r'foobar')

allgzs=[]

for file in os.listdir(wd):
    if file.endswith('asc.gz'):
       allgzs.append(file)

for gz in allgzs:


# For every 150 .gz files: 
# Create directory -- os.mkdir?
# Move files into directory  -- shutil.move?
4

5 回答 5

5

我想出了一个grouper函数来产生一个长序列的运行n

import itertools
def grouper(S, n):
    iterator = iter(S)
    while True:
        items = list(itertools.islice(iterator, n))
        if len(items) == 0:
            break
        yield items

从那里,您可以非常简洁地执行您想要的操作:

import glob, os, shutil
fnames = sorted(glob.glob('*asc.gz'))
for i, fnames in enumerate(grouper(fnames, 150)):
    dirname = 'batch%d' % i
    os.mkdir(dirname)
    for fname in fnames:
        shutil.move(fname, dirname)
于 2012-09-24T06:25:40.883 回答
2

让我们看看,我将列举在这种情况下我会做什么。

  • 获取文件列表 - X
  • 循环遍历所有文件 - X
  • 确保文件只有一个句点 - O
  • 过滤掉不需要的扩展 - X
  • 将想要的扩展添加到新列表 - O
  • 循环遍历新列表中的所有文件 - O
  • 将它们添加到列表中并使用计数器,以便您知道何时有 150 - O
  • 当您有 150 个文件时,将它们全部移动 - O
  • 回到循环 - O
  • 一旦你遍历所有并复制,你就完成了。

你有它。此外,这绝不是最有效或最好的方法,这就是我的方式。

编辑:示例代码:

wantedexts = [".jpg",".png",".randomext"]
wantedfiles = []

for f in files: #the files from the folder
    allowedext = 0
    for exts in wantedexts:
        if f.endswith(exts):
            allowedext = 1
            break
    if allowedext:
        wantedfiles.append(f)

counter = 0
countertwo = 0 #used to tell when you get to the end of the files
copyfiles = []
for f in wantedfiles:
    if counter == 150 or countertwo == len(wantedfiles):
        for fc in copyfiles:
            copy    #too lazy to type in real copy code
        counter = 0
        copyfiles = []
    copyfiles.append(f)
    counter += 1
    countertwo += 1

几乎为您编写了代码,但无论如何。Countertwo 用于复制最后的项目(因为可能会剩下一些)。

于 2012-09-24T05:07:30.583 回答
2

如果您热衷于保留已经编写的代码,这里有一个直观的方式来完成它:

import os
import shutil

wd = os.chdir(r'foobar')

allgzs=[]

for file in os.listdir(wd):
    if file.endswith('asc.gz'):
       allgzs.append(file)

n = 1
name = "subdir%i" %n
for gz in allgzs:
    if not os.path.exists(name):
        os.mkdir(name)
    shutil.move(gz, name)
    if len(os.listdir(name)) == 150:
        n += 1
        name = "subdir%i" %n
于 2012-09-24T06:24:05.517 回答
1

我只是在这里使用列表推导来制作文件名列表。您的名单将来自os.listdirglob.glob('*asc.gz')

>>> files = ['foo{}.gz'.format(i) for i in range(5000)]
>>> for i, fname in enumerate(files):
...     if i%150 == 0:
...         dirname = "bar{}".format(i//150)
...         os.mkdir(dirname)
...     print fname,"-->", dirname
...     shutil.move(fname, dirname)
... 
foo0.gz --> bar0
foo1.gz --> bar0
foo2.gz --> bar0
foo3.gz --> bar0
foo4.gz --> bar0
foo5.gz --> bar0
... 

这里的技巧是记录我们正在处理的文件的数量并除以将150其映射到目录中。//仅表示整数除法(与/Python2 中相同)

于 2012-09-24T05:34:27.667 回答
0

您可以为此使用glob模块

for file in glob.glob('*.gz'):
    #Do Stuff
于 2012-09-24T05:08:54.470 回答