使用shutil在python中复制文件

I have the following directory structure:


 -mailDir

     -folderA

         -sub1

         -sub2

         -inbox

            -1.txt

            -2.txt

            -89.txt

            -subInbox

            -subInbox2

     -folderB

         -sub1

         -sub2

         -inbox

            -1.txt

            -2.txt

            -200.txt

            -577.txt

目的是将收件箱文件夹下的所有txt文件复制到另一个文件夹中。为此,我尝试了以下代码


import os

from os import path

import shutil


rootDir = "mailDir"

destDir = "destFolder"


eachInboxFolderPath = []

for root, dirs, files in os.walk(rootDir):

    for dirName in dirs:

        if(dirName=="inbox"):

            eachInboxFolderPath.append(root+"\\"+dirName)


for ii in eachInboxFolderPath:

    for i in os.listdir(ii):

        shutil.copy(path.join(ii,i),destDir)

如果收件箱目录只有 .txt 文件,那么上面的代码工作正常。由于文件夹A目录下的收件箱文件夹还有其他子目录以及.txt文件,因此代码返回权限被拒绝错误。我的理解是shutil.copy 不允许复制文件夹。


目的是仅将每个收件箱文件夹中的 txt 文件复制到其他位置。如果不同收件箱文件夹中的文件名相同,我必须保留两个文件名。在这种情况下,我们如何改进代码?请注意,除了 .txt 之外,所有其他文件都只是文件夹。


GCT1015
浏览 202回答 3
3回答

富国沪深

只记得我曾经写过几个文件来解决这个确切的问题。你可以在我的 Github 上找到源代码。简而言之,这里有两个有趣的函数:list_files(loc, return_dirs=False, return_files=True, recursive=False, valid_exts=None)copy_files(loc, dest, rename=False)对于您的情况,您可以将这些函数复制并粘贴到您的项目中并copy_files像这样修改:def copy_files(loc, dest, rename=False):    # get files with full path    files = list_files(loc, return_dirs=False, return_files=True, recursive=True, valid_exts=('.txt',))    # copy files in list to dest    for i, this_file in enumerate(files):        # change name if renaming        if rename:            # replace slashes with hyphens to preserve unique name            out_file = sub(r'^./', '', this_file)            out_file = sub(r'\\|/', '-', out_file)            out_file = join(dest, out_file)            copy(this_file, out_file)            files[i] = out_file        else:            copy(this_file, dest)    return files然后就这样称呼它:copy_files('mailDir', 'destFolder', rename=True)重命名方案可能不是您想要的,但至少不会覆盖您的文件。我相信这应该可以解决您的所有问题。

江户川乱折腾

干得好:import osfrom os import pathimport shutildestDir = '<absolute-path>'for root, dirs, files in os.walk(os.getcwd()):&nbsp; &nbsp; # Filter out only '.txt' files.&nbsp; &nbsp; files = [f for f in files if f.endswith('.txt')]&nbsp; &nbsp; # Filter out only 'inbox' directory.&nbsp; &nbsp; dirs[:] = [d for d in dirs if d == 'inbox']for f in files:&nbsp; &nbsp; p = path.join(root, f)&nbsp; &nbsp; # print p&nbsp; &nbsp; shutil.copy(p, destDir)快速而简单。抱歉,我忘记了其中的部分,您还需要唯一的文件名。上述解决方案仅适用于单个收件箱文件夹中的不同文件名。要从多个收件箱复制文件并在目标文件夹中具有唯一名称,您可以尝试以下操作:import osfrom os import pathimport shutilsourceDir = os.getcwd()fixedLength = len(sourceDir)destDir = '<absolute-path>'filteredFiles = []for root, dirs, files in os.walk(sourceDir):&nbsp; &nbsp; # Filter out only '.txt' files in all the inbox directories.&nbsp; &nbsp; if root.endswith('inbox'):&nbsp; &nbsp; &nbsp; &nbsp; # here I am joining the file name to the full path while filtering txt files&nbsp; &nbsp; &nbsp; &nbsp; files = [path.join(root, f) for f in files if f.endswith('.txt')]&nbsp; &nbsp; &nbsp; &nbsp; # add the filtered files to the main list&nbsp; &nbsp; &nbsp; &nbsp; filteredFiles.extend(files)# making a tuple of file path and file namefilteredFiles = [(f, f[fixedLength+1:].replace('/', '-')) for f in filteredFiles]for (f, n) in filteredFiles:&nbsp; &nbsp; print 'copying file...', f&nbsp; &nbsp; # copying from the path to the dest directory with specific name&nbsp; &nbsp; shutil.copy(f, path.join(destDir, n))print 'copied', str(len(filteredFiles)), 'files to', destDir如果您需要复制所有文件而不仅仅是 txt 文件,则只需将条件更改f.endswith('.txt')为os.path.isfile(f)同时过滤掉文件即可。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python