在Python中展开复杂的目录结构

2024-05-15 01:17:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我想把文件从一个复杂的目录结构移到一个地方。例如,我有一个深层次的层次结构:

foo/
    foo2/
        1.jpg
    2.jpg
    ...

我希望是:

1.jpg
2.jpg
...

我目前的解决方案:

def move(destination):
    for_removal = os.path.join(destination, '\\')
    is_in_parent = lambda x: x.find(for_removal) > -1
    with directory(destination):
        files_to_move = filter(is_in_parent,
                               glob_recursive(path='.'))
    for file in files_to_move:
        shutil.move(file, destination)

定义:^{}^{}。注意,我的代码只将文件移动到它们的公共父目录,而不是任意目标。

如何将所有文件从复杂的层次结构简洁优雅地移动到单个位置?


Tags: 文件topathin目录formove层次结构
3条回答

这样做可以,如果文件发生冲突,它也会重命名文件(我注释掉了实际的移动并替换为副本):

import os
import sys
import string
import shutil

#Generate the file paths to traverse, or a single path if a file name was given
def getfiles(path):
    if os.path.isdir(path):
        for root, dirs, files in os.walk(path):
            for name in files:
                yield os.path.join(root, name)
    else:
        yield path

destination = "./newdir/"
fromdir = "./test/"
for f in getfiles(fromdir):
    filename = string.split(f, '/')[-1]
    if os.path.isfile(destination+filename):
        filename = f.replace(fromdir,"",1).replace("/","_")
    #os.rename(f, destination+filename)
    shutil.copy(f, destination+filename)

在目录中递归运行,移动文件并启动目录的move

import shutil
import os

def move(destination, depth=None):
    if not depth:
        depth = []
    for file_or_dir in os.listdir(os.path.join([destination] + depth, os.sep)):
        if os.path.isfile(file_or_dir):
            shutil.move(file_or_dir, destination)
        else:
            move(destination, os.path.join(depth + [file_or_dir], os.sep))

我不想测试将要移动的文件的名称,看我们是否已经在目标目录中。相反,此解决方案只扫描目标的子目录

import os
import itertools
import shutil


def move(destination):
    all_files = []
    for root, _dirs, files in itertools.islice(os.walk(destination), 1, None):
        for filename in files:
            all_files.append(os.path.join(root, filename))
    for filename in all_files:
        shutil.move(filename, destination)

说明:os.walk以“自顶向下”的方式递归地遍历目的地。整个文件名是用os.path.join(root,filename)调用构造的。现在,为了防止扫描目标顶部的文件,我们只需要忽略os.walk迭代的第一个元素。为此,我使用islice(iterator,1,None)。另一个更明确的方法是:

def move(destination):
    all_files = []
    first_loop_pass = True
    for root, _dirs, files in os.walk(destination):
        if first_loop_pass:
            first_loop_pass = False
            continue
        for filename in files:
            all_files.append(os.path.join(root, filename))
    for filename in all_files:
        shutil.move(filename, destination)

相关问题 更多 >

    热门问题