2016-08-10 8 views
10

मैं समान संरचनाओं के साथ कई निर्देशिकाओं को कॉपी करना चाहता हूं (उपनिर्देशिका के समान नाम हैं) लेकिन विभिन्न सामग्री तीसरे स्थान पर और उन्हें मर्ज करें। साथ ही, मैं कुछ फ़ाइल एक्सटेंशन को अनदेखा करना चाहता हूं और उन्हें कॉपी नहीं करना चाहता हूं।कुछ एक्सटेंशन को छोड़कर निर्देशिकाओं की प्रतिलिपि बनाना और विलय करना


मैंने पाया कि अकेले पहला काम आसानी से distutils.dir_util पुस्तकालय से copy_tree() समारोह द्वारा नियंत्रित किया जा सकता है। यहां मुद्दा यह है कि copy_tree() फ़ाइलों को अनदेखा नहीं कर सकता है; यह बस प्रतियां सब कुछ ..

distutils.dir_util.copy_tree() - उदाहरण के

dirs_to_copy = [r'J:\Data\Folder_A', r'J:\Data\Folder_B'] 
destination_dir = r'J:\Data\DestinationFolder' 
for files in dirs_to_copy: 
    distutils.dir_util.copy_tree(files, destination_dir) 
    # succeeds in merging sub-directories but copies everything. 
    # Due to time constrains, this is not an option. 

दूसरा कार्य (फ़ाइलें बाहर रखने का विकल्प के साथ नकल) के लिए वहाँ copytree() है इस समय shutil लाइब्रेरी से कार्य करें। उस के साथ समस्या यह है कि यह अब फ़ोल्डरों को मिला नहीं सकते क्योंकि गंतव्य निर्देशिका मौजूद नहीं चाहिए ..

shutil.copytree() - उदाहरण के

dirs_to_copy = [r'J:\Data\Folder_A', r'J:\Data\Folder_B'] 
destination_dir = r'J:\Data\DestinationFolder' 
for files in dirs_to_copy: 
    shutil.copytree(files, destination_dir, ignore=shutil.ignore_patterns("*.abc")) 
    # successfully ignores files with "abc" extensions but fails 
    # at the second iteration since "Destination" folder exists.. 

वहाँ कुछ है कि का सबसे अच्छा प्रदान करता है दोनों दुनिया या क्या मुझे इसे स्वयं कोड करना है?

+0

कैसे [shutil copytree उदाहरण] में सुधार करने के बारे में (https://docs.python.org/2/library/shutil.html#copytree-example) इतना है कि यह से त्रुटि को पकड़ने से डुप्लिकेट निर्देशिका पर ध्यान नहीं देता ' makedirs'? –

+0

@ पीटर ब्रितन लेकिन अगर मैं ऐसा करता हूं, तो यह फ़ोल्डरों को पूरी तरह से सही कर देगा? और, मुझे उनकी सामग्री की आवश्यकता है। –

+0

नहीं, यह नहीं होगा। यह सभी फ़ोल्डरों को बनाने का प्रयास करेगा, एक अपवाद मारा जाएगा (जिसे आप एक नई कोशिश के साथ निगलते हैं ... उस पंक्ति के चारों ओर हैंडर को छोड़कर) और फिर निर्देशिका चलने के लिए आगे बढ़ें (फाइलों की प्रतिलिपि बनाना या आवश्यकतानुसार रिकर्सिंग)। –

उत्तर

3

रूप PeterBrittain का सुझाव दिया, shutil.copytree() के अपने खुद के संस्करण जाने का रास्ता लिख ​​रहा था। नीचे कोड है। ध्यान दें कि os.makedirs()if ब्लॉक में केवल अंतर ही है।

from shutil import copy2, copystat, Error, ignore_patterns 
import os 


def copytree_multi(src, dst, symlinks=False, ignore=None): 
    names = os.listdir(src) 
    if ignore is not None: 
     ignored_names = ignore(src, names) 
    else: 
     ignored_names = set() 

    # -------- E D I T -------- 
    # os.path.isdir(dst) 
    if not os.path.isdir(dst): 
     os.makedirs(dst) 
    # -------- E D I T -------- 

    errors = [] 
    for name in names: 
     if name in ignored_names: 
      continue 
     srcname = os.path.join(src, name) 
     dstname = os.path.join(dst, name) 
     try: 
      if symlinks and os.path.islink(srcname): 
       linkto = os.readlink(srcname) 
       os.symlink(linkto, dstname) 
      elif os.path.isdir(srcname): 
       copytree_multi(srcname, dstname, symlinks, ignore) 
      else: 
       copy2(srcname, dstname) 
     except (IOError, os.error) as why: 
      errors.append((srcname, dstname, str(why))) 
     except Error as err: 
      errors.extend(err.args[0]) 
    try: 
     copystat(src, dst) 
    except WindowsError: 
     pass 
    except OSError as why: 
     errors.extend((src, dst, str(why))) 
    if errors: 
     raise Error(errors) 
0

यदि आप सीधे शिल का उपयोग करना चाहते हैं, तो त्रुटि को छोड़ने के लिए os.makedirs के लिए एक गर्म पैच यहां है।

import os 
os_makedirs = os.makedirs 
def safe_makedirs(name, mode=0777): 
    if not os.path.exists(name): 
     os_makedirs(name, mode) 
os.makedirs = safe_makedirs 

import shutil 

dirs_to_copy = [r'J:\Data\Folder_A', r'J:\Data\Folder_B'] 
destination_dir = r'J:\Data\DestinationFolder' 
if os.path.exists(destination_dir): 
    shutil.rmtree(destination_dir) 
for files in dirs_to_copy: 
    shutil.copytree(files, destination_dir, ignore=shutil.ignore_patterns("*.abc")) code here 
+0

लेकिन 'shutil.rmtree (destination_dir) को निष्पादित करने पर मैं अपनी सामग्री को हटाने जा रहा हूं जो एक निर्देशिका से आ जाएगा जो दोबारा कॉपी नहीं किया जाएगा। अंत में मैं 'dirs_to_copy' सूची पर अंतिम निर्देशिका की एक प्रति के साथ समाप्त होने जा रहा हूं और बाकी सब कुछ कॉपी और फिर हटा दिया गया होगा। –

संबंधित मुद्दे

 संबंधित मुद्दे