鱼C论坛

 找回密码
 立即注册
查看: 3371|回复: 12

[已解决]提取word标题或者第一行前几个字为文件名,重名文件如何添加序号?

[复制链接]
发表于 2022-7-8 10:31:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
感谢坛友lightninng前面提供的代码,解决了提取word标题为文件名这个问题,但是由于文档有些标题名字一样,所以遇到这类问题后就停止重命名了,请教论坛里的各位好心人,如何在此代码中添加一项内容:遇到重名文件,自动在后面添加序号(1)(2)(3)。


import win32com.client
import os

app = win32com.client.DispatchEx("Word.Application")
file_name=[]
for path,dirs,files in os.walk(os.getcwd()):
    for file in files:
        if (file.split(".")[-1]=="docx" or file.split(".")[-1]=="doc" )and "$" not in file:  #只处理docx或doc文件
            app.visible = False #不显示word窗口
            doc = app.Documents.Open(f'{path}\{file}')   #打开文件
            title=str(doc.paragraphs[0])    #获取第一段内容(也就是第一行,word中回车分隔的就是不同段落)
            doc.Close()    #关闭打开的文档
            os.rename(f'{path}\{file}',f"{path}\{str(title).strip()}.{file.split('.')[-1]}")   #给文件改名
            
    break #只处理当前目录,所以第一项完成后退出
app.Quit()
        
最佳答案
2022-7-8 12:26:49
本帖最后由 临时号 于 2022-7-8 12:28 编辑

如果还有一些不能作为文件名的字符,可以直接在remove_str那里添加
import win32com.client
import os

count = 0
remove_str = r"*\<>?"
app = win32com.client.DispatchEx("Word.Application")
file_name=[]
for path,dirs,files in os.walk(os.getcwd()):
    for file in files:
        if (file.split(".")[-1]=="docx" or file.split(".")[-1]=="doc" )and "$" not in file:  #只处理docx或doc文件
            app.visible = False #不显示word窗口
            doc = app.Documents.Open(f'{path}\{file}')   #打开文件
            title=str(doc.paragraphs[0])    #获取第一段内容(也就是第一行,word中回车分隔的就是不同段落)
            doc.Close()    #关闭打开的文档
            for r in remove_str:
                if r in title:
                    title = title.replace(r,'')
            while True:
                try:
                    if count == 0:
                        os.rename(f'{path}\{file}',f"{path}\{str(title).strip()}.{file.split('.')[-1]}")   #给文件改名
                    else:
                        os.rename(f'{path}\{file}',f"{path}\{str(title).strip()}({count}).{file.split('.')[-1]}")
                except FileExistsError:
                    count += 1
                else:
                    count = 0
                    break
            
    break #只处理当前目录,所以第一项完成后退出
app.Quit()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-8 10:39:32 From FishC Mobile | 显示全部楼层
加个判断不就好了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-8 10:45:07 | 显示全部楼层
qq1151985918 发表于 2022-7-8 10:39
加个判断不就好了。

主要是不会添加,大神能否帮忙一下呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-8 11:25:17 | 显示全部楼层
import win32com.client
import os

count = 0
app = win32com.client.DispatchEx("Word.Application")
file_name=[]
for path,dirs,files in os.walk(os.getcwd()):
    for file in files:
        if (file.split(".")[-1]=="docx" or file.split(".")[-1]=="doc" )and "$" not in file:  #只处理docx或doc文件
            app.visible = False #不显示word窗口
            doc = app.Documents.Open(f'{path}\{file}')   #打开文件
            title=str(doc.paragraphs[0])    #获取第一段内容(也就是第一行,word中回车分隔的就是不同段落)
            doc.Close()    #关闭打开的文档
            while True:
                try:
                    if count == 0:
                        os.rename(f'{path}\{file}',f"{path}\{str(title).strip()}.{file.split('.')[-1]}")   #给文件改名
                    else:
                        os.rename(f'{path}\{file}',f"{path}\{str(title).strip()}({count}).{file.split('.')[-1]}")
                except FileExistsError:
                    count += 1
                else:
                    count = 0
                    break
            
    break #只处理当前目录,所以第一项完成后退出
app.Quit()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-8 12:09:43 From FishC Mobile | 显示全部楼层
sjjy1813 发表于 2022-7-8 10:45
主要是不会添加,大神能否帮忙一下呢

我没在电脑前。思路给你说一下,你在文件夹内查找是不是已经有这个文件名,如果没有那么直接命名,如果有就命名为2.3.4等等,这里可以加一个循环。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-8 12:11:07 | 显示全部楼层

棒棒的,大神,还遇到个问题,就是首段里如果包含了*\<>?这种字符的情况,这样的首行就不能作为文档名了,能否在程序将这些去除后再重命名呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-8 12:17:20 | 显示全部楼层
sjjy1813 发表于 2022-7-8 12:11
棒棒的,大神,还遇到个问题,就是首段里如果包含了*\?这种字符的情况,这样的首行就不能作为文档名了, ...

可以
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-8 12:20:10 | 显示全部楼层

再次厚颜,请大神帮忙改下了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-8 12:26:49 | 显示全部楼层    本楼为最佳答案   
本帖最后由 临时号 于 2022-7-8 12:28 编辑

如果还有一些不能作为文件名的字符,可以直接在remove_str那里添加
import win32com.client
import os

count = 0
remove_str = r"*\<>?"
app = win32com.client.DispatchEx("Word.Application")
file_name=[]
for path,dirs,files in os.walk(os.getcwd()):
    for file in files:
        if (file.split(".")[-1]=="docx" or file.split(".")[-1]=="doc" )and "$" not in file:  #只处理docx或doc文件
            app.visible = False #不显示word窗口
            doc = app.Documents.Open(f'{path}\{file}')   #打开文件
            title=str(doc.paragraphs[0])    #获取第一段内容(也就是第一行,word中回车分隔的就是不同段落)
            doc.Close()    #关闭打开的文档
            for r in remove_str:
                if r in title:
                    title = title.replace(r,'')
            while True:
                try:
                    if count == 0:
                        os.rename(f'{path}\{file}',f"{path}\{str(title).strip()}.{file.split('.')[-1]}")   #给文件改名
                    else:
                        os.rename(f'{path}\{file}',f"{path}\{str(title).strip()}({count}).{file.split('.')[-1]}")
                except FileExistsError:
                    count += 1
                else:
                    count = 0
                    break
            
    break #只处理当前目录,所以第一项完成后退出
app.Quit()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-8 12:33:41 | 显示全部楼层
sjjy1813 发表于 2022-7-8 12:20
再次厚颜,请大神帮忙改下了

代码在9#
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-8 17:39:22 | 显示全部楼层

感谢大神的辛苦付出!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-12 08:40:42 | 显示全部楼层

大神,遇到个问题,就是有时候标题中有个换行或者回车,就执行不下不去了,这个换行或者回车,我用chr(10)、chr(13)这种添加,好像不咋起作用啊,这样的该如何处置呢?
测试文档如下:
链接:https://pan.baidu.com/s/1t5STQoGeJdI1eDDxHZXBzw?pwd=a9ec
提取码:a9ec
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-28 19:43:59 | 显示全部楼层
本帖最后由 sjjy1813 于 2023-2-28 19:45 编辑

我自己也研究了一下
import os
import re
from docx import Document
from docx.opc.exceptions import PackageNotFoundError

# 定义正则表达式匹配规则,匹配文件名中的非法字符
invalid_pattern = re.compile(r'[\/\\\:\*\?"\<\>\|]')

# 定义函数,将文件名中的非法字符替换为'_'
def replace_invalid_char(filename):
    return invalid_pattern.sub('_', filename)

# 定义递归函数,遍历指定路径下所有的文件夹及子文件夹
def traverse_folder(path):
    for root, dirs, files in os.walk(path):
        for filename in files:
            if filename.endswith('.doc') or filename.endswith('.docx'):
                filepath = os.path.join(root, filename)
                try:
                    doc = Document(filepath)
                    # 获取第一段的文字
                    text = doc.paragraphs[0].text.strip()
                    # 去除文件名中的非法字符
                    new_name = replace_invalid_char(text)
                    # 如果文件名已存在,则在重复的文件名后面添加数字
                    if os.path.exists(os.path.join(root, new_name + os.path.splitext(filename)[1])):
                        i = 1
                        while True:
                            new_name_with_number = f'{new_name} ({i})'
                            if not os.path.exists(os.path.join(root, new_name_with_number + os.path.splitext(filename)[1])):
                                new_name = new_name_with_number
                                break
                            i += 1
                    # 重命名文件
                    os.rename(filepath, os.path.join(root, new_name + os.path.splitext(filename)[1]))
                    # 打印文件名的修改过程
                    print(f'{filename} -> {new_name + os.path.splitext(filename)[1]}')
                except (PackageNotFoundError, IndexError):
                    # 如果文件不是有效的doc或docx文件,则跳过该文件
                    continue
        for folder in dirs:
            traverse_folder(os.path.join(root, folder))

# 指定文件夹路径
folder_path = 'C:\\文件\\2023'

# 打印提示信息
print(f'正在遍历路径 {folder_path} 下的所有文件夹及子文件夹')

# 调用递归函数,遍历指定路径下所有的文件夹及子文件夹
traverse_folder(folder_path)

# 打印结束信息
print('文件名修改完成!')
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-6-17 18:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表