2017-09-27 115 views
0

我已經廣泛地查看了此網站,我看不到符合法案的示例。我有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()模塊,所以我只能移動文件,但我似乎無法讓它工作。有人有任何想法嗎?

+0

是在同一個文件夾中的4或你手動給4路徑? – mikuszefski

+0

這4個目錄位於同一個文件夾中,它是U:\ Data \ All \ Python_Test \ Exports,它包含四個目錄,每個目錄都包含一個「Superseded」文件夾。 – Dunuts

回答

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正確設置的。

+0

謝謝。你知道如何改變這個nameList = [「U:/Data/All/PAR_Exports/ {:02d}」.format(x)for x in range(4)],以便它可以是基於字符的四個文件夾? – Dunuts

+0

@Dunuts嗨,你至少有兩種可能性:1)'nameList = [「U:/ Data/All/PAR_Exports/{}」。['a','b',' (4)範圍內的x的格式(chr(97 + x)),或者在abcd 2)'nameList = [「U:/ Data/All/PAR_Exports/{} ]'爲其他角色選擇了不同的偏移功能。並在最後提示。爲了避免在'\'或'/'路徑中混淆,使用'os.path.join()'。 – mikuszefski