2017-05-08 25 views
18

我已經在多個文件夾中的幾個文件是這樣的:如何移動和重命名放置在幾個嵌套文件夾中的文件到python中的新文件夾中?

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

UPDATE

另外,我想:

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

如果你沒有一個Python的現代版(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

我還添加了如何使用shutil,os和glob做到這一點。 –

+0

我其實是在python3! – tumbleweed

7

這是最簡單的使用Python 3的新辦pathlib模塊進行路徑操作,然後shutil.move將文件移動到正確的位置。與os.rename不同,shutil.move將像mv命令一樣工作,即使跨文件系統移動也行得通。

此代碼將用於嵌套到任意水平路徑工作 - 在路徑中的任何/\將與在目標文件名_取代,因此dir/foo/bar/baz/xyzzy.xml將被移動到new_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

非常感謝antti! – tumbleweed

相關問題