python批量处理word文档,
本文主要详细介绍如何使用Python清理重复文件。文章中的样例代码讲解的很详细,对我们学习Python很有帮助。有需要的可以参考一下。
00-1010清理重复文件清理重复文件优化1清理重复文件优化2清理重复文件优化3批量修改文件名
目录
已知条件:
我什么都不知道,只知道是个档案。
实现方法:
可以从指定的路径(或者顶层路径)开始读取,使用glob读取每个文件夹,读取文件,记录名称和大小,检查每次测试前是否读取过同名文件。如果是,判断大小是否相同。如果是这样,我们将认为它是一个重复的文件,并删除它。
代码示例如下:
#编码:utf-8
导入全球
导入os.path
Data={} #定义一个空字典,临时存储文件名。
定义清除(路径):
Result=glob.glob(path) #传入路径path并将其赋给结果
result: # for循环中的for _data确定它是否是文件夹。
如果glob.os.path.isdir (_ data) 3360 #是一个文件夹,继续将文件夹的路径传递给clear()函数,继续递归搜索。
_path=glob.os.path.join(_data, * )
清除(_路径)
Else: #如果是文件,提取文件名。
name=glob . OS . path . split(_ data)[-1]
如果 zip 在name: #中,因为有一个。zip 文件下的路径,我们目前正在测试,我们应该跳过阅读的。zip 压缩文件,否则我们将报告一个错误。
继续
F=open(_data, r) #如果是不可读模式,先读内容再判断文件名
Content=f.read() #将读取的内容分配给内容
data: #中的名称判断文件名是否已经存在于临时存储该文件名的数据字典中,如果存在,则将其删除。
_content_dict=data[name]
如果内容字典==内容:
打印(文件\ {} \ 已被删除.。格式(_数据))#调试
os.remove(_data)
else:
数据[名称]=内容
if __name__==__main__:
path=glob . OS . path . join(glob . OS . getcwd(), test_file )
清除(路径)
PS:这里需要注意的是,如果路径是根目录,会出现超级意外的结果。建议建立单独的文件夹路径进行测试。(踩这个坑我都疼.)
运行结果如下:
清理重复的文件
解决相同文件名不同路径不同内容的问题。
其实这里可以想到一个问题。可能会出现不同文件夹中存在相同文件名,但文件内容不同的情况。如果用上面的脚本来删除文件夹下的同名文件,其实是一个不严谨的操作。
这就引出了对上述脚本优化的以下要求。
在这里,我们来看看实际的数据值:data={ name 3360 { path/name 3360 content , path2/name 3360 content}}
增长
行内容的 name 为我们传入路径的根路径
通过这种二级路径与内容删除的重复文件才是一种比较合理的方式。
示例代码如下:
# coding:utf-8import glob
import os.path
data = {} # 定义一个空的字典,暂时将文件名存进来
def clear(path):
result = glob.glob(path) # 将 path 路径传入,赋值给 result
for _data in result: # for 循环判断是否是文件夹
if glob.os.path.isdir(_data): # 若是文件夹,继续将该文件夹的路径传给 clear() 函数继续递归查找
_path = glob.os.path.join(_data, *)
clear(_path)
else: # 若是文件,则将文件名提取出来
name = glob.os.path.split(_data)[-1]
if zip in name: # 因为目前我们测试的 path 下有 ".zip" 文件,所以这里跳过 .zip 压缩文件的读取否则会报错
continue
f = open(_data, r) # 判断文件名之前先将内容读取出来,若是不可读模式
content = f.read() # 将读取内容赋值给 content
if name in data: # 判断文件名是否已存在 data 这个临时存储文件名的字典内,如果存在则进行执行删除动作
# 如果不存在,则将读取到的二级路径与内容存储至 data 这个空字典内
sub_name = data[name] # 定义 sub_name 用以获取二级路径
is_delete = False # is_delete 用以记录删除状态;如果没有删除,还需要将二级路径添加至 data
for k, v in sub_name.items(): # 再次循环判断二级路径下的文件;k 为路径,v 为文件内容
print(二级路径为 \"{}\" ,.format(k), name, 内容为 \{}\ .format(v)) # 调试打印输出二级路径下文件的循环
if v == content: # 如果文件名与内容相同,则执行删除动作
print(文件 \"{}\" 被删除....format(_data)) # 调试被删除的文件
os.remove(_data) # 删除重复文件后,变更 is_delete 状态为True
is_delete = True
if not is_delete: # 如果没有删除则将 content 读取到的内容赋值给 data[name][_data]
data[name][_data] = content
else:
data[name] = {
_data: content
}
if __name__ == __main__:
path = glob.os.path.join(glob.os.getcwd(), test_file)
clear(path)
print(data)
运行结果如下:
清理重复文件的优化2
利用 hashlib模块解决读取文件过大问题
现在还有一个问题,从调试的打印输出内容可以看出,因为用以测试的 test_file 路径下的文件都比较小,所以运行起来没有太大的问题;试想一下,如果是一些比较大的文件,经过读取并存入字典的时候,就极大可能会造成内存不足等情况,所以这样直接存储内容的方法是显然不合适的。
其实也是可以解决这个问题的, 就是利用到之前学习的加密模块 ,通过 hashlib 模块将内容加密成md5 的形式, md5只是一个很短的字符串,只要原始内容不变, md5 的值就不会变(该方法也经常被用于运维环境的文件安全检测)。
所以代码中的读取文件内容的 content 就需要变更一下了:
代码示例如下:
# coding:utf-8import glob
import hashlib
import os.path
data = {} # 定义一个空的字典,暂时将文件名存进来
#data = {name: {path/name: content, path2/name: content}}
def clear(path):
result = glob.glob(path) # 将 path 路径传入,赋值给 result
for _data in result: # for 循环判断是否是文件夹
if glob.os.path.isdir(_data): # 若是文件夹,继续将该文件夹的路径传给 clear() 函数继续递归查找
_path = glob.os.path.join(_data, *)
clear(_path)
else: # 若是文件,则将文件名提取出来
name = glob.os.path.split(_data)[-1]
if zip in name: # 因为目前我们测试的 path 下有 ".zip" 文件,所以这里跳过 .zip 压缩文件的读取否则会报错
continue
f = open(_data, r) # 判断文件名之前先将内容读取出来,若是不可读模式
content = f.read() # 将读取内容赋值给 content
hash_content_obj = hashlib.md5(content.encode(utf-8)) # 将读取到的文件内容通过 md5 加密形式进行实例化
hash_content = hash_content_obj.hexdigest() # hash_content_obj 16进制字符串赋值给 hash_content
# 到这里,其实 data 存储的就是 hash_content
if name in data: # 判断文件名是否已存在 data 这个临时存储文件名的字典内,如果存在则进行执行删除动作
# 如果不存在,则将读取到的二级路径与内容存储至 data 这个空字典内
sub_name = data[name] # 定义 sub_name 用以获取二级路径
is_delete = False # is_delete 用以记录删除状态;如果没有删除,还需要将二级路径添加至 data
for k, v in sub_name.items(): # 再次循环判断二级路径下的文件;k 为路径,v 为文件内容
print(二级路径为 \"{}\" ,.format(k), name, 内容为 \{}\ .format(v)) # 调试打印输出二级路径下文件的循环
if v == hash_content: # 如果文件名与内容相同,则执行删除动作
print(文件 \"{}\" 被删除....format(_data)) # 调试被删除的文件
os.remove(_data) # 删除重复文件后,变更 is_delete 状态为True
is_delete = True
if not is_delete: # 如果没有删除则将 content 读取到的内容赋值给 data[name][_data]
data[name][_data] = hash_content
else:
data[name] = {
_data: hash_content
}
if __name__ == __main__:
path = glob.os.path.join(glob.os.getcwd(), test_file)
clear(path)
print(data)
运行结果如下:
清理重复文件的优化3
解决读取到不可读的 zip 文件报错问题
在上文中,当我们遇到读取到不可读的 zip 压缩文件时,利用的是 continue 的方式跳过。 其实这里说的 zip 不可读取其实不太严谨,因为可以采用二进制读取的方式来进行读取,但是在上文脚本中,针对读取的内容已经进行了 encode 编码,所以用 rb 这种二进制读取的方式还需要继续进行优化。
示例代码如下:
# coding:utf-8import glob
import hashlib
#data = {name: {path/name: content, path2/name: content}}
import os.path
data = {} # 定义一个空的字典,暂时将文件名存进来
def clear(path):
result = glob.glob(path) # 将 path 路径传入,赋值给 result
for _data in result: # for 循环判断是否是文件夹
if glob.os.path.isdir(_data): # 若是文件夹,继续将该文件夹的路径传给 clear() 函数继续递归查找
_path = glob.os.path.join(_data, *)
clear(_path)
else: # 若是文件,则将文件名提取出来
name = glob.os.path.split(_data)[-1]
is_byte = False # 添加一个 byte类型读取的开关(如果文件中有中文,还需要设置一下编码格式,并且将打开的文件关闭)
if zip in name: # 因为目前我们测试的 path 下有 ".zip" 文件,所以这里跳过 .zip 压缩文件的读取否则会报错
is_byte = True
f = open(_data, rb)
else:
f = open(_data, r, encoding=utf-8) # 判断文件名之前先将内容读取出来,若是不可读模式
content = f.read() # 将读取内容赋值给 content
f.close()
if is_byte:
hash_content_obj = hashlib.md5(content) # 将读取到的文件内容通过 md5 加密形式进行实例化
else:
hash_content_obj = hashlib.md5(content.encode(utf-8))
hash_content = hash_content_obj.hexdigest() # hash_content_obj 16进制字符串赋值给 hash_content
# 到这里,其实 data 存储的就是 hash_content
if name in data: # 判断文件名是否已存在 data 这个临时存储文件名的字典内,如果存在则进行执行删除动作
# 如果不存在,则将读取到的二级路径与内容存储至 data 这个空字典内
sub_name = data[name] # 定义 sub_name 用以获取二级路径
is_delete = False # is_delete 用以记录删除状态;如果没有删除,还需要将二级路径添加至 data
for k, v in sub_name.items(): # 再次循环判断二级路径下的文件;k 为路径,v 为文件内容
print(二级路径为 \"{}\" ,.format(k), name, 内容为 \{}\ .format(v)) # 调试打印输出二级路径下文件的循环
if v == hash_content: # 如果文件名与内容相同,则执行删除动作
print(文件 \"{}\" 被删除....format(_data)) # 调试被删除的文件
os.remove(_data) # 删除重复文件后,变更 is_delete 状态为True
is_delete = True
if not is_delete: # 如果没有删除则将 content 读取到的内容赋值给 data[name][_data]
data[name][_data] = hash_content
else:
data[name] = {
_data: hash_content
}
if __name__ == __main__:
path = glob.os.path.join(glob.os.getcwd(), test_file)
clear(path)
for k, v in data.items():
for _k, v in v.items():
print(文件路径为 \"{}\" ,.format(_k), 内容为 \{}\ .format(v))
运行结果如下:
批量修改文件名
其实也很简单,依然是使用我们最近学习的 shutil 与 glob 模块(参考上一章节的文件查找与递归实现的方式)。
已知条件:
知道文件名需要被修改的指定字符串(即需要被修改的文件名)
实现方法:
通过循环,将指定的目标字符串加入或修改文件名称中含有的字符串
代码示例如下:
# coding:utf-8import glob
import os.path
import shutil
利用for循环及递归这样的方式,通过 glob 去读取到 test_file 下所有的内容
通过循环按照循环的每一个索引,把每一个文件添加上索引标
def filename_update(path):
result = glob.glob(path)
for index, data in enumerate(result): # for 循环枚举:如果是文件夹则进行递归,如果是文件则加上索引值
if glob.os.path.isdir(data):
_path = glob.os.path.join(data, *)
filename_update(_path)
else:
path_list = glob.os.path.split(data)
name = path_list[-1]
new_name = {}_{}.format(index, name)
new_data = glob.os.path.join(path_list[0], new_name)
shutil.move(data, new_data)
if __name__ == __main__:
path = glob.os.path.join(glob.os.getcwd(), test_file)
filename_update(path)
运行结果如下:
可能这里大家有注意到 "test_file" 文件加下没有 "0_*"开头的索引,其实并不是没有索引,而是我们的脚本中只重命名了文件,文件夹被过滤掉了。
到此这篇关于Python自动化办公之清理重复文件详解的文章就介绍到这了,更多相关Python清理重复文件内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。