2017-05-08 13 views
18

मैं इस तरह कई फ़ोल्डरों में कई फ़ाइलें:पाइथन के साथ एक नए एकल फ़ोल्डर में कई नेस्टेड फ़ोल्डर्स में रखे दस्तावेज़ों को कैसे स्थानांतरित और नामित करें?

dir 
├── 0 
│   ├── 103425.xml 
│   ├── 105340.xml 
│   ├── 109454.xml 
│ 
│── 1247 
│   └── doc.xml 
├── 14568 
│   └── doc.xml 
├── 1659 
│   └── doc.xml 
├── 10450 
│   └── doc.xml 
├── 10351 
│   └── doc.xml 

मैं कैसे एक ही फ़ोल्डर प्रत्येक के लिए फ़ोल्डर का नाम जोड़कर में सभी दस्तावेजों निकाल सकते हैं चले गए दस्तावेज़:

new_dir 
├── 0_103425.xml 
├── 0_105340.xml 
├── 0_109454.xml 
├── 1247_doc.xml 
├── 14568_doc.xml 
├── 1659_doc.xml 
├── 10450_doc.xml 
├── 10351_doc.xml 

मैं निकालने की कोशिश की उन लोगों के साथ:

import os 

for path, subdirs, files in os.walk('../dir/'): 
    for name in files: 
     print(os.path.join(path, name)) 

अद्यतन

+०१२३५१६४१०६

इसके अलावा, मैं करने की कोशिश की करने के लिए:

import os, shutil 
from glob import glob 

files = [] 
start_dir = os.getcwd() 
pattern = "*.xml" 

for dir,_,_ in os.walk('../dir/'): 
    files.extend(glob(os.path.join(dir,pattern))) 
for f in files: 
    print(f) 
    shutil.move(f, '../dir/') 

ऊपर मुझे प्रत्येक फ़ाइल का रास्ता दे दिया। हालांकि, मुझे समझ नहीं आता नाम बदलने और उन्हें ले जाने के लिए कैसे:

--------------------------------------------------------------------------- 
Error          Traceback (most recent call last) 
<ipython-input-50-229e4256f1f3> in <module>() 
    10 for f in files: 
    11  print(f) 
---> 12  shutil.move(f, '../dir/') 

/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/shutil.py in move(src, dst, copy_function) 
    540   real_dst = os.path.join(dst, _basename(src)) 
    541   if os.path.exists(real_dst): 
--> 542    raise Error("Destination path '%s' already exists" % real_dst) 
    543  try: 
    544   os.rename(src, real_dst) 

Error: Destination path '../data/230948.xml' already exists 

उपरोक्त त्रुटि से पता चलता कारण है कि मैं अपने फ़ोल्डर के साथ इसका नाम बदलना चाहते हैं।

उत्तर

8

कैसे आप के लिए काम करता है?

import os 
import pathlib 

OLD_DIR = 'files' 
NEW_DIR = 'new_dir' 

p = pathlib.Path(OLD_DIR) 
for f in p.glob('**/*.xml'): 
    new_name = '{}_{}'.format(f.parent.name, f.name) 
    f.rename(os.path.join(NEW_DIR, new_name)) 

आप (3.5+) आप भी सिर्फ ग्लोब, ओएस, और shutil उपयोग कर सकते हैं अजगर का आधुनिक संस्करण नहीं है, तो:

import os 
import glob 
import shutil 


for f in glob.glob('files/**/*.xml'): 
    new_name = '{}_{}'.format(os.path.basename(os.path.dirname(f)), os.path.basename(f)) 
    shutil.move(f, os.path.join('new_dir', new_name)) 
+0

वाह .... यह आसान था, मुझे 'pathlib' के बारे में पता नहीं था। – tumbleweed

+2

मैंने यह भी जोड़ा कि आप इसे शटल, ओएस और ग्लोब के साथ कैसे कर सकते हैं। –

+0

मैं वास्तव में python3 में हूँ! – tumbleweed

7

यह अजगर 3 की नई के साथ क्या करना सबसे आसान है पथ संचालन के लिए pathlib मॉड्यूल, और फिर उनके सही स्थानों में फ़ाइलों हिल के लिए shutil.moveos.rename के विपरीत, shutil.movemv आदेश की तरह काम करते हैं और यहां तक ​​कि पार से फाइल सिस्टम चाल के लिए सही ढंग से व्यवहार करेंगे।

इस कोड को किसी भी स्तर के लिए नेस्ट पथ के लिए काम करेंगे - किसी भी / या \ रास्तों में लक्ष्य फ़ाइल नाम में _ से बदल दिया जाएगा, ताकि dir/foo/bar/baz/xyzzy.xmlnew_dir/foo_bar_baz_xyzzy.xml में ले जाया जाएगा।

from pathlib import Path 
from shutil import move 

src = Path('dir') 
dst = Path('new_dir') 

# create the target directory if it doesn't exist 
if not dst.is_dir(): 
    dst.mkdir() 

# go through each file 
for i in src.glob('**/*'): 
    # skip directories and alike 
    if not i.is_file(): 
     continue 

    # calculate path relative to `src`, 
    # this will make dir/foo/bar into foo/bar 
    p = i.relative_to(src) 

    # replace path separators with underscore, so foo/bar becomes foo_bar 
    target_file_name = str(p).replace('/', '_').replace('\\', '_') 

    # then do rename/move. shutil.move will always do the right thing 
    # note that it *doesn't* accept Path objects in Python 3.5, so we 
    # use str(...) here. `dst` is a path object, and `target_file_name 
    # is the name of the file to be placed there; we can use the/operator 
    # instead of os.path.join. 
    move(str(i), str(dst/target_file_name)) 
+0

धन्यवाद एन्टी, महान answe! – tumbleweed

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

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