python - 如何使用python3将路径中的文件夹移动到Windows中的另一个路径?
问题描述
我需要一个脚本来移动源文件夹中的所有内容并创建/替换到目标文件夹,而不删除目标中的任何现有文件/文件夹。test1 文件夹的内容将是一个 html 文件以及一些 png 格式的图像。
源路径:C:\Users\USERNAME\Documents\LocalFolder\reports\v2
源文件夹名称:test1
目标路径:T:\remoteReports\myTests
复制时要创建的路径: \LocalFolder\reports\v2
从源复制到目标的文件夹:test1
destinaton 中的最终路径: T:\remoteReports\myTests\LocalFolder\reports\v2\test1
我从堆栈溢出中获取了一段代码并将其用于我的应用程序,但运行脚本并没有在目标中创建路径和文件夹。
import time
import os
import random
import shutil
import pathlib
def move_files(root_src_dir,root_dst_dir):
print(root_src_dir)
print(root_dst_dir)
for src_dir, dirs, files in os.walk(root_src_dir):
dst_dir = src_dir.replace(root_src_dir,root_dst_dir, 1)
if not os.path.exists(dst_dir):
os.makedirs(dst_dir)
for file_ in files:
src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file):
# in case of the src and dst are the same file
if os.path.samefile(src_file, dst_file):
continue
os.remove(dst_file)
shutil.move(src_file, dst_dir)
srcPath = os.path.join("C:", "Users", os.getlogin(),"Documents", "LocalFolder", "v2", "test1")
dstPath = os.path.join("T:", "remoteReports", "myTests", "LocalFolder", "v2", "test1")
move_files(srcPath,dstPath )
如果有人可以指导我,这将很有帮助!
解决方案
您可以使用pathlib
将所有文件从一个文件夹复制到另一个文件夹:
from pathlib import Path
from shutil import copy
src = Path(r"C:\Users\USERNAME\Documents\LocalFolder\reports\v2")
dst = Path(r"T:\remoteReports\myTests\LocalFolder\reports\v2")
for file in src.iterdir():
if file.is_file() and not (dst / file.name).is_file():
copy(file, dst)
如果要复制包括子目录及其内容的整个树,可以申请os.walk()
:
from pathlib import Path
from os import walk
from shutil import copy
src = Path(r"C:\Users\USERNAME\Documents\LocalFolder\reports\v2")
dst = Path(r"T:\remoteReports\myTests\LocalFolder\reports\v2")
for dir_name, _, filenames in walk(src):
src_path = Path(dir_name)
dst_path = dst / src_path.relative_to(src)
if not dst_path.is_dir():
dst_path.mkdir()
for file in filenames:
dst_file = dst_path / file
if not dst_file.is_file():
copy(src_path / file, dst_path)
或者您可以从我首先建议的代码中创建函数并递归使用它:
from pathlib import Path
from shutil import copy
def copy_folder(src_path, dst_path):
if not dst_path.is_dir():
dst_path.mkdir()
for file in src_path.iterdir():
if file.is_dir():
copy_folder(file, dst_path / file.relative_to(src_path)) # recursion
elif file.is_file() and not (dst_path / file.name).is_file():
copy(file, dst_path)
src = Path(r"C:\Users\USERNAME\Documents\LocalFolder\reports\v2")
dst = Path(r"T:\remoteReports\myTests\LocalFolder\reports\v2")
copy_folder(src, dst)
但是您实际上并不需要手动实现所有这些,因为shutil.copytree()
已经存在并且与我之前提供的所有选项完全相同。重要提示:如果目标路径中的目录已经存在,您应该传递dirs_exist_ok
参数以不引发异常。
from shutil import copy, copytree
from os.path import exists
src = r"C:\Users\USERNAME\Documents\LocalFolder\reports\v2"
dst = r"T:\remoteReports\myTests\LocalFolder\reports\v2"
copytree(src, dst, copy_function=lambda s, d: not exists(d) and copy(s, d), dirs_exist_ok=True)
这里我使用lambda
了 which check does file already exists 来不覆盖它,如果你不关心文件是否会被覆盖,你可以省略这个参数。
如果要移动所有文件,可以传递shutil.move()
给copy_function
:
from shutil import move, copytree
...
copytree(src, dst, copy_function=move, dirs_exist_ok=True)
它将移动所有文件,但保留树目录。如果要复制所有目录树并将其从源中删除,可以调用shutil.copytree()
and shutil.rmtree()
:
from shutil import copytree, rmtree
...
copytree(src, dst, dirs_exist_ok=True)
rmtree(src)