Python实现自动合并文档(制作生成小程序)

有时我们需要从大量文档中根据一些关键词查找内容,一个一个文档打开查找很费时间,可以把它们合并生成一个文件,查找就方便多了。通过Python实现,步骤如下:

1. 生成需要合并的文件列表

首先导入模块和常量定义

from os import walk,path,listdir
from time import time,sleep
rootdirs = [r'E:\python\merge_all_files'] #需要合并的路径
extends = ['.txt','.py','.sql'] #需要合并的文件扩展名
newfile = 'E:\python\merge_all_files\mergy.txt' #合并后生成的文件名

如果不需要遍历子文件夹,直接遍历所需路径下制定扩展名的文件生成列表:

paths = set()
for rootdir in rootdirs:
    for file in listdir(rootdir):
        for extend in extends:
            if(path.join(rootdir, file).endswith(extend)):
                paths.add(path.join(rootdir, file)) #支持中文名称
                break        
paths = list(paths)
paths.sort(reverse=True)
print(paths)

如果需要遍历子文件夹,不论子文件夹有多少层,均可一次全部遍历完成:

rootdirs = [r'E:\python\merge_all_files']
extends = ['.txt','.py','.sql']
newfile = 'E:\python\merge_all_files\mergy1.txt'
paths = set()
for rootdir in rootdirs:
    for root, dirs, files in walk(rootdir):
        for file in files:
            if path.join(root, file) == newfile:
                continue
            for extend in extends:
                if (path.join(root, file).endswith(extend)):
                    paths.add(path.join(root, file)) #支持中文名称
                    break
paths = list(paths)
paths.sort(reverse=True)
print(paths)

2. 将文件列表中的文件内容合并生成文件

直接循环遍历列表中的文件执行合并

#创建新的文件
f = open(newfile,'w',encoding='utf-8')

# 将之前获取到的文件夹(含子文件夹)下所有文件的路径及名称里的内容写进新建的文件里
for i in paths:
    try:
        f.writelines(i+'\n\n')
        for line in open(i,'r',encoding='utf-8'):
            f.writelines(line)
        f.writelines('\n\n\n\n\n')
        print('已完成合并:{}'.format(i))
    except:
        print('无法读取文件:{}'.format(i))
f.close()   #保存并关闭新建的文件

由于文件编码不同,经常会出现读取失败的情况,因此,可列出多个编码,如果失败则尝试下一个编码:

encodes = ("utf-8;gbk;utf-8-sig;gb2312;unicode;ascii").split(';')
excepts = []
#创建新的文件
f = open(newfile,'w',encoding='utf-8')

k = len(paths)
for encode in encodes:
    i = len(paths)
    if i==0: break
    while i:
        #i = paths.pop(0)
        try:
            f.writelines(paths[i-1]+'\n\n')
            for line in open(paths[i-1],'r',encoding=encode):
                f.writelines(line)
            f.writelines('\n\n\n\n\n')
            print(paths.pop(i-1),'已完成合并,使用的编码为:{}'.format(encode))
            i -= 1
        except:
    #       print('无法读取文件:{}'.format(i))
            #excepts.append(i)
            i -= 1

f.close()   #保存并关闭新建的文件

print('已成功合并{}个文件到{}中'.format(k-len(paths),newfile))
if paths:
    print('其中以下文件读取失败\n{}'.format(';\n'.join(paths)))

3. 制作生成小程序

封装成小程序的话,要考虑更多普遍情况,增加一些输入和输出提示。生成小程序后,可以不依赖Python环境,拷贝到任意位置使用,打包方法参考我另一篇文章,生成的exe文件6M左右(高级模式输入我的用户昵称解锁)

from os import walk,path,listdir
from time import time,sleep

while True:
    count = 0
    name = input("请选择运行模式: 直接回车可进入默认模式 \n1.默认模式: 合并当前文件夹(含子文件夹)下所有.txt/.py/.sql文件,并输出到当前文件夹下mergy.txt文件 \n2.高级模式: 请输入作者名字(英文、中文、拼音均可-_-)解锁 \n3.直接退出: 请输入N\n")
    while True:
        if name in ['Jogarys','JOGARYS','jogarys','Jogary','JOGARY','jogary','jo','JO','Jo','','N','n','1','3']:
            break
        elif name=='2':
            name = input("请输入作者名字(英文、中文、拼音均可):")
            continue
        elif count==2:
            print("\nSorry,我也帮不了你了,ByeBye!")
            break
        else:
            count += 1
            name = input("名字输错啦,你还有{}次机会:".format(3-count))
            continue

    #运行Python过程中输入文件夹路径及合并后的文件路径及名称
    if name in ('N','n','3'):
        break
    elif count==2:
        sleep(3)
        break
    elif name in ('','1'):
        rootdirs = [".\\"]
        sub = "Y"
        extends = ".txt;.py;.sql".split(';')
        encodes = "utf-8;gbk;utf-8-sig;gb2312;unicode;ascii".split(';')
        newfile = ".\\mergy.txt"
    else:
        rootdirs = (input("输入要合并的文件夹路径,多个路径用分号分割,默认为当前路径,例如输入 D:\\1;D:\\2 \n") or (".\\")).split(';')
        sub = input("是否遍历所有子文件夹,默认为Y:Y/N \n") or ("Y")
        extends = (input("输入要查找的文件扩展名,多个用分号分割,默认为.txt;.py;.sql,例如输入 .txt;.py \n") or (".txt;.py;.sql")).split(';')
        encodes = (input("输入编码格式,多个用分号分割,默认为utf-8;gbk;utf-8-sig;gb2312;unicode;ascii\n") or ("utf-8;gbk;utf-8-sig;gb2312;unicode;ascii")).split(';')
        newfile = input("输入合并后的文件路径及名称,默认输出到当前目录下mergy.txt,例如输入 D:\my_mergy.txt \n") or (".\\mergy.txt")
    #rootdirs = [r'.\AI名企班-BI', r'.\AI核心班-BI']   #固定文件夹路径
    #newfile = r'.\merge.py'  #固定合并后的新文件路径及名称
    paths = set()   #存放文件夹(含子文件夹)下所有文件的路径及名称
    
    print("开始合并:") 
    start = time()
    #获取文件夹(含子文件夹)下所有文件的路径及名称
    if sub in ("Y","y"):
        for rootdir in rootdirs:
            for root, dirs, files in walk(rootdir):
#                print(root, '\n', dirs, '\n', files, '\n')
                for file in files:
                    if path.join(root, file) == newfile:
                        continue                    
                    for extend in extends:
                        if (path.join(root, file).endswith(extend)):
                            paths.add(path.join(root, file)) #支持中文名称
                            break
    else:
        for rootdir in rootdirs:
            for file in listdir(rootdir):
                for extend in extends:
                    if(path.join(rootdir, file).endswith(extend)):
                        paths.add(path.join(rootdir, file)) #支持中文名称
                        break        
    #print('文件个数:',len(paths))
    paths = list(paths)
    paths.sort(reverse=True)
    #print(paths)
    #创建新的文件
    excepts = []
    f = open(newfile,'w',encoding='utf-8')
    
    # 将之前获取到的文件夹(含子文件夹)下所有文件的路径及名称里的内容写进新建的文件里
    k = len(paths)
    for encode in encodes:
        i = len(paths)
        if i==0: break
        while i:
            #i = paths.pop(0)
            try:
                f.writelines(paths[i-1]+'\n\n')
                for line in open(paths[i-1],'r',encoding=encode):
                    f.writelines(line)
                f.writelines('\n\n\n\n\n')
                print(paths.pop(i-1),'已完成合并')
                i -= 1
            except:
        #       print('无法读取文件:{}'.format(i))
                #excepts.append(i)
                i -= 1
    
    f.close()   #保存并关闭新建的文件
    end = time()
    
    print('已成功合并{}个文件到{}中,用时:{:.2f}秒'.format(k-len(paths),newfile,end-start))
    if paths:
        print('其中以下文件读取失败\n{}'.format(';\n'.join(paths)))
    a = input("是否继续合并其他文件(Y/N)")
    if a in ('Y','y'):
        continue
    else:
        break

运行小程序界面如下:

最后奉上我打包好的小程序,可直接下载使用(高级模式输入我的昵称解锁)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值