用最新的文件夹和文件替换

问题描述

我想将文件夹和文件从源目录复制到另一个目标目录。每个目录都包含子文件夹和许多文件
到目前为止,我尝试了以下代码,灵感来自 Stackoverflow 中的一篇文章

import os
import shutil

root_src_dir = r'C:\....'
root_dst_dir  = r'C:\....'

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.copy2(src_file,dst_dir)

对于相同的文件夹和文件名,此代码将目标目录与源目录等同。这可以替换目标中最新的文件夹和文件,这是一场灾难,而我希望将最新的保留在两个目录中,因为它们具有相同的文件夹和文件名。

解决方法

这是我写的程序。它是一种交互式的,还具有移动和删除功能以及复制功能。并根据扩展名过滤数据。

import os
import shutil
from os.path import join
from time import perf_counter
print('Written By : SaGaR')
print('Applies operation on all the files with specified ext. to the destination path specified:')
scandir=input('Enter the path to scan(absolute or relative path):')
print(f'You entered :{scandir}')
choice = input('Enter operation to perform(move|copy|delete|list):').lower()
EXCLUDE=['Android','DCIM','documents','WhatsApp','MIUI','bluetooth'] #exclude some system folder on android . Add your one also. 
if choice == 'copy' or choice =='move':
    dest=input('Enter the destination path(absolute or relative path):')
    print(f'You entered :{dest}')
    EXCLUDE.append(dest)
DATA_TYPES=input('Enter Data types to filter(comma-seprated)(ex.- jpg,txt): ').split(',')
files2=[]
print('*'*5,'FINDING FILES')
for root,dirs,files in os.walk(scandir):
    for file in files:
        for typ in DATA_TYPES:
            if file.endswith(typ):
                a = join(root,file)
                print(root,end='')
                print('-->',file)
                files2.append(a)
    for directory in EXCLUDE:
        if directory in dirs:
            dirs.remove(directory)

            
def copy_move_files():
    start=perf_counter()
    print('-'*5,f'Trying To {choice.capitalize} Files')
    if not os.path.isdir(dest):
        print(f'{dest} does not exists')
        print(f'Creating {dest} directory')
        os.mkdir(dest)
    else:
        print(f'{dest} exists')
    for file in files2:
        fpath=os.path.join(dest,os.path.split(file)[-1])
        try:
            if not os.path.exists(fpath):
                if choice=='move':
                    
                    shutil.move(file,dest)
                    print(f'{file.split("/")[-1]} Moved Successfully')
                if choice=='copy':
                    shutil.copy(file,dest)
                    print(f'{file.split("/")[-1]} Copied Successfully')
            else:
                print(f'{file.split("/")[-1]} Already in destination folder')
        except shutil.SameFileError:
            print(f'{file.split("/")[-1].strip()} Already Exists in the destination directory. Add the Destination directory to EXCLUDE ')
    end = perf_counter() - start
    print(f'Operation took {end} second(s)')
      
            
def delete_files():
    print('-'*5,'Trying To Delete Files')
    for file in files2:
        os.remove(file)
        print(f'{file} deleted')


if choice == 'copy' or choice=='move':
    copy_move_files()
elif choice == 'delete':
    delete_files()
else:
    print('No valid or "list" option detected\nOnly listing Files')
print('Exiting the program Now')
,

这是使用shutil.copytree 和my_copy 函数的解决方案。

在 my_copy 中有一个 if 语句来检查哪个是最新的文件。

import os
import shutil
def my_copy(src,dst):
    print(src)
    print(dst)
    if not os.path.exists(dst):
        shutil.copy2(src,dst)
    else:   
        if os.path.getmtime(src) > os.path.getmtime(dst):
            shutil.copy2(src,dst)
    return True
    
def rec_copy():

    root_src_dir = r'C:\...'
    root_dst_dir  = r'C:\...'
    try:
        if not os.path.exists(root_dst_dir):
            print(os.path.exists(root_dst_dir))
            os.makedirs(root_dst_dir)
        print(os.path.exists(root_dst_dir)) 
        shutil.copytree(root_src_dir,root_dst_dir,copy_function=my_copy,dirs_exist_ok=True)
            
    except Exception as err:
        print(err)