前言

这个程序陆陆续续开发了几天,正好我在学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的使用演示。

代码

 # coding=gbk

 # PathMerge.py
# 作者:freecode
# 创建时间:2016.4.9 20:15
# 作用:
# 合并并两个目录/文件夹。
# 将目录A合并到目录B,同级目录下,
# 将A中有,B中没有的目录完全复制到B中;
# 将A中没有,B中有的目录不做改动;
# 将A中做了修改的文件,在B的同级目录下创建一个副本。(注意不是覆盖)
#
# 适应场景:
# 一般A是从B复制过来的文件夹,做了修改后,想合并回B。
# 这样在A中做的一些改动我们就不知道了,这个程序的作用是,
# 将A中修改的部分在B中更新。
#
# 版本:
# 将修改后的文件完全复制过去
# 旧的文件创建副本
# 基于文件的MD5值判断是否修改过
# import os
import shutil
import time
import hashlib
import sys def Help(): # 输出帮助文档
print """
PathMerge.py
作者:freecode
创建时间:2016.4.9 20:15
作用:
合并并两个目录/文件夹。
将目录A合并到目录B,同级目录下,
将A中有,B中没有的目录完全复制到B中;
将A中没有,B中有的目录不做改动;
将A中做了修改的文件,在B的同级目录下创建一个副本。(注意不是覆盖) 适应场景:
一般A是从B复制过来的文件夹,做了修改后,想合并回B。
这样在A中做的一些改动我们就不知道了,这个程序的作用是,
将A中修改的部分在B中更新。 版本:
将修改后的文件完全复制过去
旧的文件创建副本
基于文件的MD5值判断是否修改过
""" def GetFileMd5(filename): # 计算文件的md5值
if not os.path.isfile(filename):
return
myhash = hashlib.md5()
f = file(filename,'rb')
while True:
b = f.read(8096)
if not b :
break
myhash.update(b)
f.close()
return myhash.hexdigest() def isModify(A_file,B_file): # 判断两个文件是否相同,如果不同,表示修改过
# 参数需是绝对路径
return GetFileMd5(A_file) != GetFileMd5(B_file) def Stamp2Time(Stamp): # 将时间戳转换成时间显示格式
timeArray = time.localtime(Stamp)
Time = time.strftime("%Y年%m月%d日 %H时%M分%S秒 旧文件副本", timeArray)
return Time def Merge(A_path,B_path): # 合并两个目录
B_paths = os.listdir(B_path) # 获取当前B中的目录结构
for fp in os.listdir(A_path): # 遍历当前A目录中的文件或文件夹
A_new_path = os.path.join(A_path,fp) # A中的文件或目录
B_new_path = os.path.join(B_path,fp) # B中对应的文件或路径,不一定存在 if os.path.isdir(A_new_path): # A中的目录
if os.path.exists(B_new_path): # 如果在B中存在
Merge(A_new_path,B_new_path) # 继续合并下一级目录
else: # 如果在B中不存在
print '[目录]\t%s ===> %s' %(A_new_path,B_new_path)
shutil.copytree(A_new_path,B_new_path) # 完全复制目录到B elif os.path.isfile(A_new_path): # A中的文件
if os.path.exists(B_new_path): # 如果在B中存在
s = os.stat(B_new_path)
if isModify(A_new_path,B_new_path) == True: # 如果该文件修改过
# 创建副本
suffix = B_new_path.split('.')[-1] # 得到文件的后缀名
# 将B中原文件创建副本
B_copy_path = B_new_path[:-len(suffix)-1]+"(%s)."%(Stamp2Time(s.st_mtime))+suffix
print '[副本]\t%s ===> %s' %(A_new_path,B_copy_path)
shutil.copy2(B_new_path,B_copy_path)
# 将A中修改后文件复制过来
print '[文件]\t%s ===> %s' %(A_new_path,B_new_path)
shutil.copy2(A_new_path,B_new_path)
else: # 如果该文件没有修改过
pass # 不复制 else: # 如果在B中不存在
# 将该文件复制过去
print '[文件]\t%s ===> %s' %(A_new_path,B_new_path)
shutil.copy2(A_new_path,B_new_path) # 运行模式
if __name__=='__main__':
print """
欢迎使用PathMerge!
本程序将会把目录A合并到目录B,即 A ===> B
将A目录中修改的内容在B目录中更新
合并规则具体见 PathMerge.Help()
"""
if len(sys.argv) == 1:
path1 = raw_input('请输入A目录:').strip()
path2 = raw_input('请输入B目录:').strip()
elif len(sys.argv) == 2:
path1 = sys.argv[1].strip()
print 'A目录为:%s\n' % (path1)
path2 = raw_input('请输入B目录:').strip()
elif len(sys.argv) == 3:
path1 = sys.argv[1].strip()
print 'A目录为:%s\n' % (path1)
path2 = sys.argv[2].strip()
print 'B目录为:%s\n' % (path2)
else:
print 'ERROR:参数错误!\n参数最多有三个!\n'
raw_input('\n请按回车键(Enter)退出……')
sys.exit(0)
# 去除目录的引号
if path1[0]=='\"':
path1 = path1[1:-1]
if path2[0]=='\"':
path2 = path2[1:-1] print """
开始合并目录 %s
   到目录 %s
%s ===> %s
""" %(path1,path2,path1,path2) try:
print '合并中……'
Merge(path1,path2)
print ''
except Exception,e:
print '合并失败!'
print '失败原因:\n',e
else:
print '合并成功!' raw_input('\n请按回车键(Enter)退出……')

工具特性

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

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

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

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

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

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

注意

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

参考资料

python 文件拷贝、移动

原创声明

Freecode# : www.cnblogs.com/yym2013

python开发目录合并小工具 PathMerge的更多相关文章

  1. Python开发目录

    Python开发目录 Python之三目运算符 Python之文件的基本操作

  2. Python 使用 PyQt5 开发的关机小工具

    前两天简单认识了一下PyQt5,通过练习开发了一款在Window下自定义关机的小工具,代码如下 import os,sys,time from PyQt5 import QtCore,QtWidget ...

  3. supervisor python开发的进程管理工具

    Supervisor (http://supervisord.org) 是一个用 Python 写的进程管理工具,可以很方便的用来启动.重启.关闭进程(不仅仅是 Python 进程).除了对单个进程的 ...

  4. python 3.6 MJ小工具

    2017.07.14 update 做了个界面,不需要使用cmd命令行+文件路径的方式来使用了: 链接如下: http://www.cnblogs.com/chenyuebai/p/7150382.h ...

  5. 几款Android开发人员必备小工具

    在这里我介绍一下我常常在Android Studio里面使用的小工具吧,这些工具都能够在plugin里面搜索到. (当然了哈.我也是从网上找的.用着挺方便的,在这里总结一下) Gsonformat: ...

  6. WPF开发查询加班小工具

    先说一下,我们公司是六点下班,超过7点开始算加班,但是加班的时间是从六点开始计算,以0.5个小时为计数,就是你到了六点半,不算加班半小时,但是加班到七点半,就是加班了一个半小时. 一.打卡记录 首先, ...

  7. Python开发——目录

    Python基础 Python开发——解释器安装 Python开发——基础 Python开发——变量 Python开发——[选择]语句 Python开发——[循环]语句 Python开发——数据类型[ ...

  8. 【实战小项目】python开发自动化运维工具--批量操作主机

    有很多开源自动化运维工具都很好用如ansible/salt stack等,完全不用重复造轮子.只不过,很多运维同学学习Python之后,苦于没小项目训练.本篇就演示用Python写一个批量操作主机的工 ...

  9. Python开发接水果小游戏

    我研发的Python游戏引擎Pylash已经更新到1.4了.如今我们就来使用它完毕一个极其简单的小游戏:接水果. 下面是游戏截图: 游戏操作说明:点击屏幕左右两边或者使用键盘方向键控制人物移动.使人物 ...

随机推荐

  1. 回顾yii的学习进程 总结了一下的发展过程

    如果看到这篇文章,我想说恭喜你 不用,你可以先放下学习yii了  我先学在把结论发给你们节省精力 yii2的学习教程:http://www.digpage.com/recent_update.html ...

  2. C/C++的编译过程

    预处理(Preprocess). 使用Preprocessor Directives将一些代码替换成另一些代码. 例如将include替换成它指向的文件包含的代码. 编译成目标文件(Compiatio ...

  3. 并查集(union-find)算法

    动态连通性 . 假设程序读入一个整数对p q,如果所有已知的所有整数对都不能说明p和q是相连的,那么将这一整数对写到输出中,如果已知的数据可以说明p和q是相连的,那么程序忽略p q继续读入下一整数对. ...

  4. 【USACO 2.3】The Longest Prefix

    题意: 给你一个少于200000的字符串,求最长的可以划分为给定词典里的单词的前缀. 题解: dp[i]表示第i位结尾的前缀是否可行,然后枚举每一位如果dp[i-1]==1,枚举所有单词,匹配成功的单 ...

  5. angular指令深度学习篇

    angular指令深度学习-过滤器 limitTo ... <body ng-app="app" > <div ng-controller="myCtr ...

  6. Alpha阶段第一次Scrum Meeting

    Scrum Meeting   Alpha 情况简述 Alpha阶段第一次Scrum Meeting 敏捷开发起始时间 2016/10/18 00:00 敏捷开发终止时间 2016/10/20 00: ...

  7. 使用mosh取代ssh提高n2n网络连接稳定性

    上文实现了远程n2n访问树莓派,但是ssh协议在网络状况不好的时候命令会卡住.这里发现了一个mosh协议,可以增强稳定性,使用后效果明显. 背景:使用n2n之后,在比较差的网络环境下,经常会被time ...

  8. Java编程中的美好

    java程序员如何写出"优美"代码,动力节点告诉你怎么办: 1.注释尽可能全面 对于方法的注释应该包含详细的入参和结果说明,有异常抛出的情况也要详细叙述:类的注释应该包含类的功能说 ...

  9. Google Map API V3开发(3)

    Google Map API V3开发(1) Google Map API V3开发(2) Google Map API V3开发(3) Google Map API V3开发(4) Google M ...

  10. win7计划任务执行php脚本方法

    第一步:编写bat文件 方法1:php方法 方法2:exploere浏览器 电脑上新建一个txt文本,把代码放进去.然后把他另存为xxx.bat explorer "http://网址/e/ ...