• python开发目录合并小工具 PathMerge


    前言

    这个程序陆陆续续开发了几天,正好我在学Python,就一边做一边学,倒是学到不少东西。

    不得不说python是快速开发的好工具。

    程序做了一些改进,这两天又忙着毕设,现在才想起来发到博客上。想想回头github也要启用起来,不能继续荒废了……

    如果嫌运行python程序不方便的话,可以直接使用exe可执行文件版本。

    exe发布器在这里:使用pyInstaller发布PathMerge的exe版本(py转换成exe)

    废话不多说,我介绍一下这个工具。

    应用场景

    在日常使用中,我们往往需要把一个文件夹拷到另一个文件夹下面,做一些修改之后,再将改动的文件夹合并回去。

    例如,从优盘中把一个要用的文件夹拷到电脑上,在pc机上工作,之后你需要将修改后的文件夹再拷回优盘中带走。

    这个时候问题来了。

    如果你做的修改不多,我们可以简单的把修改的文件复制回去,这个时候你清楚的记得你到底修改了哪些文件。

    但是如果你对很多文件做了改动,并且还创建了几个文件或者文件夹,导致目录结构变得十分复杂,最后你自己都记不起来到底哪些文件做了哪些改动,目录做了哪些更新,这个时候你要把文件夹合并回去就有些凌乱了……

    So,你需要一个工具去帮你记忆你做的改动,自动的帮你合并文件夹,并且不会丢失任何文件。

    这个时候这个小工具就可以派上用场了~

    下面演示一下怎么用。

    使用演示

    现在有两个工作空间

    工作空间1是你之前做好的一个工程或者文件夹,里面放满了文件,目录结构复杂。

    详细目录:

    工作空间2是你现在要工作的目录,现在是空的。

    我们把要用的文件夹拷过来

    并在里面做一些改动。

    这里不放图了,总之我创建了一个文件夹,创建了两个文件,修改了三个文件……现在目录结构变成这样:

    大家看到,1/下多了一个文件夹33,里面多了两个文件111.txt和222.txt,我还修改了一个txt文件,一个ppt文件和一个word文件。

    下面运行PathMerge:

    输入A目录(修改的文件夹)和B目录(原文件夹),要将A==>B,A合并到B。

    回车开始合并:

    合并成功!

    合并的记录都列在上面了,如果名称相同的文件会将旧文件创建一个副本,修改后的文件直接复制过去,程序中没有删除文件的代码,可放心食用。

    上图可知复制了三个文件,创建了三个旧文件副本,另外复制了创建的目录。

    将工作空间2中1文件做的所有改动都包含了进去。

    以上,就是PathMerge的使用演示。

    代码

      1 # coding=gbk
      2 
      3 # PathMerge.py
      4 # 作者:freecode
      5 # 创建时间:2016.4.9 20:15
      6 # 作用:
      7 #   合并并两个目录/文件夹。
      8 #   将目录A合并到目录B,同级目录下,
      9 #   将A中有,B中没有的目录完全复制到B中;
     10 #   将A中没有,B中有的目录不做改动;
     11 #   将A中做了修改的文件,在B的同级目录下创建一个副本。(注意不是覆盖)
     12 #
     13 # 适应场景:
     14 #   一般A是从B复制过来的文件夹,做了修改后,想合并回B。
     15 #   这样在A中做的一些改动我们就不知道了,这个程序的作用是,
     16 #   将A中修改的部分在B中更新。
     17 #
     18 # 版本:
     19 #   将修改后的文件完全复制过去
     20 #   旧的文件创建副本
     21 #   基于文件的MD5值判断是否修改过
     22 #
     23 
     24 import os
     25 import shutil
     26 import time
     27 import hashlib
     28 import sys
     29 
     30 def Help():     # 输出帮助文档
     31   print """  
     32 PathMerge.py
     33 作者:freecode
     34 创建时间:2016.4.9 20:15
     35 作用:
     36     合并并两个目录/文件夹。
     37     将目录A合并到目录B,同级目录下,
     38     将A中有,B中没有的目录完全复制到B中;
     39     将A中没有,B中有的目录不做改动;
     40     将A中做了修改的文件,在B的同级目录下创建一个副本。(注意不是覆盖)
     41 
     42 适应场景:
     43     一般A是从B复制过来的文件夹,做了修改后,想合并回B。
     44     这样在A中做的一些改动我们就不知道了,这个程序的作用是,
     45     将A中修改的部分在B中更新。
     46 
     47 版本:
     48     将修改后的文件完全复制过去
     49     旧的文件创建副本
     50     基于文件的MD5值判断是否修改过
     51 """
     52 
     53 def GetFileMd5(filename):       # 计算文件的md5值
     54     if not os.path.isfile(filename):
     55         return
     56     myhash = hashlib.md5()
     57     f = file(filename,'rb')
     58     while True:
     59         b = f.read(8096)
     60         if not b :
     61             break
     62         myhash.update(b)
     63     f.close()
     64     return myhash.hexdigest()
     65 
     66 def isModify(A_file,B_file):        # 判断两个文件是否相同,如果不同,表示修改过
     67     # 参数需是绝对路径
     68     return  GetFileMd5(A_file) != GetFileMd5(B_file)
     69 
     70 def Stamp2Time(Stamp):      # 将时间戳转换成时间显示格式
     71     timeArray = time.localtime(Stamp)
     72     Time = time.strftime("%Y年%m月%d日 %H时%M分%S秒 旧文件副本", timeArray)
     73     return Time
     74 
     75 def Merge(A_path,B_path):       # 合并两个目录
     76     B_paths = os.listdir(B_path)    # 获取当前B中的目录结构
     77     for fp in os.listdir(A_path):   # 遍历当前A目录中的文件或文件夹
     78         A_new_path = os.path.join(A_path,fp)    # A中的文件或目录
     79         B_new_path = os.path.join(B_path,fp)    # B中对应的文件或路径,不一定存在
     80 
     81         if os.path.isdir(A_new_path):           # A中的目录
     82             if os.path.exists(B_new_path):      # 如果在B中存在
     83                 Merge(A_new_path,B_new_path)    # 继续合并下一级目录
     84             else:   # 如果在B中不存在
     85                 print '[目录]	%s ===> %s' %(A_new_path,B_new_path)
     86                 shutil.copytree(A_new_path,B_new_path)   # 完全复制目录到B
     87                 
     88         elif os.path.isfile(A_new_path):        # A中的文件
     89             if os.path.exists(B_new_path):      # 如果在B中存在
     90                 s = os.stat(B_new_path)
     91                 if isModify(A_new_path,B_new_path) == True:  # 如果该文件修改过
     92                     # 创建副本
     93                     suffix = B_new_path.split('.')[-1]  # 得到文件的后缀名
     94                     # 将B中原文件创建副本
     95                     B_copy_path = B_new_path[:-len(suffix)-1]+"(%s)."%(Stamp2Time(s.st_mtime))+suffix
     96                     print '[副本]	%s ===> %s' %(A_new_path,B_copy_path)
     97                     shutil.copy2(B_new_path,B_copy_path)
     98                     # 将A中修改后文件复制过来
     99                     print '[文件]	%s ===> %s' %(A_new_path,B_new_path)
    100                     shutil.copy2(A_new_path,B_new_path)
    101                 else:  # 如果该文件没有修改过
    102                     pass    # 不复制
    103                 
    104             else:   # 如果在B中不存在
    105                 # 将该文件复制过去
    106                 print '[文件]	%s ===> %s' %(A_new_path,B_new_path)
    107                 shutil.copy2(A_new_path,B_new_path)
    108 
    109 # 运行模式
    110 if __name__=='__main__':
    111     print """
    112         欢迎使用PathMerge!
    113         本程序将会把目录A合并到目录B,即 A ===> B
    114         将A目录中修改的内容在B目录中更新
    115         合并规则具体见 PathMerge.Help()
    116         """
    117     if len(sys.argv) == 1:
    118         path1 = raw_input('请输入A目录:').strip()
    119         path2 = raw_input('请输入B目录:').strip()
    120     elif len(sys.argv) == 2:
    121         path1 = sys.argv[1].strip()
    122         print 'A目录为:%s
    ' % (path1)
    123         path2 = raw_input('请输入B目录:').strip()
    124     elif len(sys.argv) == 3:
    125         path1 = sys.argv[1].strip()
    126         print 'A目录为:%s
    ' % (path1)
    127         path2 = sys.argv[2].strip()
    128         print 'B目录为:%s
    ' % (path2)
    129     else:
    130         print 'ERROR:参数错误!
    参数最多有三个!
    '
    131         raw_input('
    请按回车键(Enter)退出……')
    132         sys.exit(0)
    133     # 去除目录的引号
    134     if path1[0]=='"':
    135       path1 = path1[1:-1]
    136     if path2[0]=='"':
    137       path2 = path2[1:-1]
    138 
    139     print """
    140 开始合并目录 %s
    141    到目录 %s
    142 %s ===> %s
    143 """ %(path1,path2,path1,path2)
    144 
    145     try:
    146         print '合并中……'
    147         Merge(path1,path2)
    148         print ''
    149     except Exception,e:
    150         print '合并失败!'
    151         print '失败原因:
    ',e
    152     else:
    153         print '合并成功!'
    154 
    155     raw_input('
    请按回车键(Enter)退出……')
    156     

    工具特性

    1、可识别加“”的目录和不加“”的目录。

    2、使用MD5识别文件是否修改。

    MD5识别文件的内容见上一篇博文:python计算文件的md5值

    3、可传递参数,用来写脚本。例:

    4、原文件夹内的旧文件不会被删除,而是创建一个带有时间戳的副本。修改过的文件直接复制过去。

      这样不用担心合并之后文件莫名其妙的丢失啦。使用该工具不会有文件删除操作。

    注意

    Sorry,目前仅支持windows环境……

    参考资料

    python 文件拷贝、移动

    原创声明

    Freecode# : www.cnblogs.com/yym2013

  • 相关阅读:
    不意外:Facebook上市遭遇滑铁卢
    最不浪漫的17个人生片段
    解決IE不能訪問ftp的問題
    關於Micrsoft.VisualBasic.dll中Strings.StrConv的第三個參數LocaleID引起的問題
    一個水平垂直的Div頁面效果
    常用的CSS命名规则[轉載]
    asp.net連接數據庫時出現問題的解決方法
    javascript訪問剪貼板的內容
    offsetTop、offsetLeft、offsetWidth、offsetHeight的用法[轉載]
    微软正版软件验证的手工解决方案
  • 原文地址:https://www.cnblogs.com/yym2013/p/5507853.html
Copyright © 2020-2023  润新知