我在几个文件夹中有几个文件,如下所示:
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
以上错误显示了我想用其文件夹重命名的原因。
答案 0 :(得分:9)
这对你有什么用?
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+),你也可以使用glob,os和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))
答案 1 :(得分:8)
使用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))