仅移动目录中的文件

时间:2017-09-27 11:48:14

标签: python-2.7 directory shutil

我在这个网站上看了很多,我看不到符合条件的例子。我有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()模块,所以我只能移动文件,但我似乎无法让它工作。有人有什么想法吗?

1 个答案:

答案 0 :(得分:0)

这对我有用:

import os

#from:
# https://stackoverflow.com/questions/1158076/implement-touch-using-python
# 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)
                #https://stackoverflow.com/questions/8858008/how-to-move-a-file-in-python
                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:
# https://stackoverflow.com/questions/2187269/python-print-only-the-message-on-warnings
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正确设置了权限。