2017-09-27 4 views
0

J'ai beaucoup regardé ce site et je ne peux pas voir un exemple qui corresponde à la facture. J'ai 4 répertoires dont chacun contient un certain nombre de fichiers et un autre répertoire appelé «Superseded». J'essaie d'écrire un script qui va déplacer tous les fichiers de chaque dossier dans le dossier 'Superseded' mais je n'ai pas de chance.Déplacer uniquement les fichiers dans les répertoires

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) 

Je ne peux que cela fonctionne pour un répertoire et même alors seulement quand je l'ai fait le répertoire de destination en dehors du répertoire GLA si cela fait sens.

Je sais qu'il existe un module os.path.isfile() pour que je puisse seulement déplacer les fichiers mais je n'arrive pas à le faire fonctionner. Est-ce que quelqu'un a des idées?

+0

sont les 4 dans le même dossier ou donnez-vous les 4 chemins manuellement? – mikuszefski

+0

Les 4 répertoires se trouvent dans le même dossier, c'est U: \ Data \ All \ Python_Test \ Exports et il contient les quatre répertoires, chacun contenant un dossier 'Superseded'. – Dunuts

Répondre

0

Cela fonctionne pour moi:

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() 

Mais, réfléchissez bien ce qu'il faut faire si le fichier existe déjà dans votre dossier de destination. os.walk peut également être quelque chose que vous voulez regarder.

La mise en œuvre de plusieurs options pour le comportement de copie peut ressembler à ceci:

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." 

De plus on peut vérifier les autorisations de fichiers comme, par exemple, os.remove() peut soulever une exception. Dans ce cas, cependant, je suppose que les autorisations sont correctement définies par l'OP.

+0

Merci. Savez-vous comment je pourrais changer cette nameList = ["U:/Data/All/PAR_Exports/{: 02d}". Format (x) pour x dans la gamme (4)] de sorte qu'il peut être quatre dossiers basés sur des caractères? – Dunuts

+0

@Dunuts Bonjour, vous avez ici au moins deux possibilités: 1) 'nameList = [" U:/Data/All/PAR_Exports/{} ". Format (x) pour x dans ['a', 'b', ' c ',' d ']] 'ou dans le cas de abcd 2)' nomDeListe = ["U: /Données/Tous/ PAR_Exports/ {}". format (chr (97 + x)) pour x dans la plage (4) ] 'a choisi différentes fonctions de décalage pour les autres caractères. Et un conseil à la fin. Pour éviter toute confusion dans les chemins avec '\' ou '/', utilisez 'os.path.join()'. – mikuszefski