仅移动目录中的文件

Moving only Files in Directories

我在这个网站上看了很多遍,但找不到符合要求的示例。我有 4 个目录,每个目录包含一些文件和另一个名为 'Superseded' 的目录。我正在尝试编写一个脚本,将每个文件夹中的所有文件移动到 'Superseded' 文件夹中,但我没有任何运气。

import os, shutil
source = r'U:\Data\All\Python_Test\Exports\GLA'
dest = r'U:\Data\All\Python_Test\Exports\Superseded'
listofFiles = os.listdir(source)
 for f in listofFiles:
    fullPath = source + "/" + f
    shutil.move(fullPath, dest)

我只能让它在一个目录下工作,即便如此,只有在我将目标目录设置在 GLA 目录之外的情况下才有意义。

我知道有一个 os.path.isfile() 模块,因此我只能移动文件,但我似乎无法让它工作。有人有什么想法吗?

这对我有用:

import os

#from:
# 
# I use this to create some empty file to move around later
def touch(fname, times=None):
    fhandle = open(fname, 'a')
    try:
        os.utime(fname, times)
    finally:
        fhandle.close()


# this function is only to create the folders and files to be moved        
def create_files_in_known_folders():
    nameList=["source_dir_{:02d}".format(x) for x in range(4)]
    for name in nameList:
        path=os.path.expanduser(os.path.join("~",name))
        if not os.path.exists(path):
            os.mkdir(path)
        ssPath=os.path.join(path,"superseded")  
        if not os.path.exists(ssPath):
            os.mkdir(ssPath)  
        for i in range(3):
            filename="{}_{:02d}.dat".format(name,i)
            filepath=os.path.join(path, filename)
            if not os.path.exists(filepath):
                touch(filepath)

# THIS is actually the function doing what the OP asked for
# there many details that can be tweaked
def move_from_known_to_dest():
    # here my given names from above
    nameList=["source_dir_{:02d}".format(x) for x in range(4)]
    # and my destination path
    destPath=os.path.expanduser(os.path.join("~","dest"))
    # not interested in files that are in subfolders
    # if those would exist change to os.walk and 
    # exclude the destination folder with according if...:
    for name in nameList:
        path=os.path.expanduser(os.path.join("~",name))
        dirList=os.listdir(path)
        print path
        for fileName in dirList:
            filePath=os.path.join(path, fileName)
            print filePath
            if os.path.isfile(filePath):
                destPath=os.path.join(path,"superseded",fileName)
                print destPath
                #alternatively you can chose to 1) overwrite ()might not work 2)delete first 3) not copy
                # another option is to check for existence and if 
                # present add a number to the dest-file-name
                # use while loop to check for first non-present number 
                assert not os.path.exists(destPath), "file {} already exits".format(destPath)
                #
                os.rename( filePath, destPath)



if __name__=="__main__":
    create_files_in_known_folders()
    #break here and check that filestructure and files have been created
    move_from_known_to_dest()

但是,如果文件已经存在于目标文件夹中,请仔细考虑该怎么做。 os.walk 也可能是你想看的内容。

为复制行为实施多个选项可能如下所示:

import warnings

#from:
# 
formatwarning_orig = warnings.formatwarning
warnings.formatwarning = lambda message, category, filename, lineno, line=None: \
    formatwarning_orig(message, category, filename, lineno, line='')


def move_from_known_to_dest_extra(behaviour='overwrite'):
    assert behaviour in ['overwrite','leave','accumulate'], "unknown behaviour: {}".format(behaviour)
    nameList=["source_dir_{:02d}".format(x) for x in range(4)]
    destPath=os.path.expanduser(os.path.join("~","dest"))
    for name in nameList:
        path=os.path.expanduser(os.path.join("~",name))
        dirList=os.listdir(path)
        for fileName in dirList:
            filePath=os.path.join(path, fileName)
            if os.path.isfile(filePath):
                destPath=os.path.join(path,"superseded",fileName)
                # simplest case...does not exist so copy
                if not os.path.exists(destPath):
                    os.rename( filePath, destPath)
                else:
                    if behaviour=='leave':
                        warnings.warn( "Warning! Not copying file: {}; file {} already exists!".format(filePath, destPath))
                    elif behaviour =='overwrite':
                        os.remove(destPath)
                        # documentation states:
                        # On Windows, if dst already exists, OSError will be raised even if it is a file.
                        os.rename( filePath, destPath)
                        warnings.warn( "Warning!Overwriting file: {}.".format(destPath))
                    elif behaviour=='accumulate': #redundant but OK
                        addPost=0
                        while True:
                            newDestPath=destPath+"{:04d}".format(addPost)
                            if not os.path.exists(newDestPath):
                                break
                            addPost+=1
                            assert addPost < 10000, "Clean up the mess!"
                        os.rename( filePath, newDestPath)
                    else:
                        assert 0, "Unknown copy behaviour requested."

此外,可能会检查文件权限,例如,os.remove() 可能会引发异常。但是,在这种情况下,我假设权限已由 OP 正确设置。