Python批量命名某目录下的所有图片名字
1. 需求
在实验过程中,我们会拍摄很多照片,这时就会遇到需要大量重命名照片的情况。比如我们有10个组,每个组有10只鼠,每只鼠要拍至少5张照片,要求每张照片以1-1,1-2…2-1,2-2…10-1,10-2这样的方式命名。如果人工一张一张去命名,会耗时久且枯燥无聊。所以可以借助Python批量命名图片解决这个需求。
如下图:
在C:\Users\Jock\Desktop\手机
目录下,存在1-10个文件夹,1-10个文件夹下又有1-10个文件夹,每个文件夹下有数量不等的图片需要重命名。
要求:把里面的图片以文件夹名-1
的格式命名,即1-1,2-1…10-1.
2. Python解决需求
2.1 文件遍历的方法
os.scandir(path='.')
,Python3.5后提供,通过减少os.stat()调用提升速度,通常比os.listdir()快,返回一个包含path路径下所有目录和文件的迭代器。os.listdir(path='.')
,返回一个包含path下所有目录和文件的列表.os.walk(top, topdown=True, onerror=None, followlinks=False)
,得到一个三元tupple(dirpath, dirnames, filenames),返回的是一个生成器.
- dirpath 是一个string,代表起始目录路径,
- dirnames 是一个list,包含了dirpath下所有子目录的名字(即文件夹名字)
- filenames 是一个list,包含了dirpath下非目录文件的名字(即所有文件名),这些名字不包含路径信息,如果需要得到全路径,需要使用os.path.join(dirpath,name)得到全路径。
示例:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
path = r'C:\Users\Jock\Desktop\手机\1'
filelist_1 = os.scandir(path)
filelist_2 = os.listdir(path)
filelist_3 = os.walk(path)
print('os.scandir()返回的类型为:' + str(type(filelist_1)))
print('打印os.scandir(path)结果为:' + str(filelist_1))
print('os.listdir()返回的类型为:' + str(type(filelist_2)))
print('打印os.listdir(path)结果为:' + str(filelist_2))
print('os.walk()返回的类型为:' + str(type(filelist_3)))
print('打印os.walk(path)结果为:' + str(filelist_3))
print('通过for遍历os.scandir()的结果为:')
for i in filelist_1:
print(i, end=' ')
print()
print('通过for遍历os.listdir()的结果为:')
for i in filelist_2:
print(i, end=' ')
print()
print('通过for遍历os.walk()的结果为:')
for i in filelist_3:
print(i)
输出:
os.scandir()返回的类型为:<class 'nt.ScandirIterator'>
打印os.scandir(path)结果为:<nt.ScandirIterator object at 0x0000006283C99940>
os.listdir()返回的类型为:<class 'list'>
打印os.listdir(path)结果为:['1', '10', '2', '3', '4', '5', '6', '7', '8', '9']
os.walk()返回的类型为:<class 'generator'>
打印os.walk(path)结果为:<generator object walk at 0x00000062848FAB88>
通过for遍历os.scandir()的结果为:
<DirEntry '1'> <DirEntry '10'> <DirEntry '2'> <DirEntry '3'> <DirEntry '4'> <DirEntry '5'> <DirEntry '6'> <DirEntry '7'> <DirEntry '8'> <DirEntry '9'>
通过for遍历os.listdir()的结果为:
1 10 2 3 4 5 6 7 8 9
通过for遍历os.walk()的结果为:
('C:\\Users\\Jock\\Desktop\\手机\\1', ['1', '10', '2', '3', '4', '5', '6', '7', '8', '9'], [])
('C:\\Users\\Jock\\Desktop\\手机\\1\\1', [], ['10aeafb51acf7b6d7.jpg', '11a3ea555d8ca7e8b.jpg', '1c522c2da3c36757a.jpg', '1cd650c965469dce8.jpg', '1cef3f66b78d0890a.jpg', '1d44bdb1c5e5f709a.jpg', '1db75d79d8a32ba44.jpg', '1dbe080c29fb0aeff.jpg', '1e1ee156f444b6aef.jpg', '1fb7b968a62eb10ef.jpg'])
('C:\\Users\\Jock\\Desktop\\手机\\1\\10', [], ['1a17a03c384cfc78e.jpg', '1a2c208410ae84d1f.jpg', '1a57323b77d9c53e5.jpg', '1ab22cb8d8464e096.jpg', '1abde5c9a60044485.jpg', '1b34c5ccc4c4fd548.jpg', '1b9b78195adbb4bc4.jpg', '1ba3c0a1d956429e2.jpg', '1c16e93d0bf77a31f.jpg'])
('C:\\Users\\Jock\\Desktop\\手机\\1\\2', [], ['1a17a03c384cfc78e.jpg', '1a2c208410ae84d1f.jpg', '1a57323b77d9c53e5.jpg', '1ab22cb8d8464e096.jpg', '1abde5c9a60044485.jpg', '1b34c5ccc4c4fd548.jpg', '1b9b78195adbb4bc4.jpg', '1ba3c0a1d956429e2.jpg', '1c16e93d0bf77a31f.jpg'])
('C:\\Users\\Jock\\Desktop\\手机\\1\\3', [], ['1a17a03c384cfc78e.jpg', '1a2c208410ae84d1f.jpg', '1a57323b77d9c53e5.jpg', '1ab22cb8d8464e096.jpg', '1abde5c9a60044485.jpg', '1b34c5ccc4c4fd548.jpg', '1b9b78195adbb4bc4.jpg', '1ba3c0a1d956429e2.jpg', '1c16e93d0bf77a31f.jpg'])
('C:\\Users\\Jock\\Desktop\\手机\\1\\4', [], ['1a17a03c384cfc78e.jpg', '1a2c208410ae84d1f.jpg', '1a57323b77d9c53e5.jpg', '1ab22cb8d8464e096.jpg', '1abde5c9a60044485.jpg', '1b34c5ccc4c4fd548.jpg', '1b9b78195adbb4bc4.jpg', '1ba3c0a1d956429e2.jpg', '1c16e93d0bf77a31f.jpg'])
('C:\\Users\\Jock\\Desktop\\手机\\1\\5', [], ['1a17a03c384cfc78e.jpg', '1a2c208410ae84d1f.jpg', '1a57323b77d9c53e5.jpg', '1ab22cb8d8464e096.jpg', '1abde5c9a60044485.jpg', '1b34c5ccc4c4fd548.jpg', '1b9b78195adbb4bc4.jpg', '1ba3c0a1d956429e2.jpg', '1c16e93d0bf77a31f.jpg'])
('C:\\Users\\Jock\\Desktop\\手机\\1\\6', [], ['1a17a03c384cfc78e.jpg', '1a2c208410ae84d1f.jpg', '1a57323b77d9c53e5.jpg', '1ab22cb8d8464e096.jpg', '1abde5c9a60044485.jpg', '1b34c5ccc4c4fd548.jpg', '1b9b78195adbb4bc4.jpg', '1ba3c0a1d956429e2.jpg', '1c16e93d0bf77a31f.jpg'])
('C:\\Users\\Jock\\Desktop\\手机\\1\\7', [], ['1a17a03c384cfc78e.jpg', '1a2c208410ae84d1f.jpg', '1a57323b77d9c53e5.jpg', '1ab22cb8d8464e096.jpg', '1abde5c9a60044485.jpg', '1b34c5ccc4c4fd548.jpg', '1b9b78195adbb4bc4.jpg', '1ba3c0a1d956429e2.jpg', '1c16e93d0bf77a31f.jpg'])
('C:\\Users\\Jock\\Desktop\\手机\\1\\8', [], ['1a17a03c384cfc78e.jpg', '1a2c208410ae84d1f.jpg', '1a57323b77d9c53e5.jpg', '1ab22cb8d8464e096.jpg', '1abde5c9a60044485.jpg', '1b34c5ccc4c4fd548.jpg', '1b9b78195adbb4bc4.jpg', '1ba3c0a1d956429e2.jpg', '1c16e93d0bf77a31f.jpg'])
('C:\\Users\\Jock\\Desktop\\手机\\1\\9', [], ['1a17a03c384cfc78e.jpg', '1a2c208410ae84d1f.jpg', '1a57323b77d9c53e5.jpg', '1ab22cb8d8464e096.jpg', '1abde5c9a60044485.jpg', '1b34c5ccc4c4fd548.jpg', '1b9b78195adbb4bc4.jpg', '1ba3c0a1d956429e2.jpg', '1c16e93d0bf77a31f.jpg'])
2.2 文件重命名
os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)
,把src重命名为dst, 返回值为None,不支持跨平台。os.replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)
, 把src重命名为dst, 返回值为None,支持跨平台.不过要慎用,因为如果dst存在则会被覆盖掉。会导致误删文件。建议用rename。os.renames(old, new)
,递归重命名src为dst。返回值为None。
具体可以看我的另外一篇Python os.rename()和os.renames()用法的区别
其他的关于os
和os.path
模块的使用可以参考我这篇文章Python os和os.path模块常用方法小结
2.3 需求分析
因为是要批量命名C:\Users\Jock\Desktop\手机
目录下及其所有子文件夹中的所有图片,需要用到递归查找,所以os.scandir()和os.listdir()实现起来比较麻烦,所以选择更合适的os.walk()来实现需求。
2.4 Python代码实现
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2019/7/20 20:01
@author: Jock
"""
import os
class BatchRenamePics(object):
"""
批量命名目录下的所有图名[.jpg,.png]
命名格式:1-1,1-2...2-1,2-2...10-1,10-2...eg
"""
def __init__(self, path):
# 设置起始路径path
self.path = path
def rename(self):
allfile = os.walk(self.path)
# j用于计数,统计有多少张照片被重命名
j = 0
# 遍历每一层目录,从上到下的顺序
for dirpath, dirnames, filenames, in allfile:
# 得到当前文件夹的名字tail
tail = os.path.split(dirpath)[1]
# i用于命名
i = 0
# 遍历filenames中的每一个文件
for each in filenames:
# 如果文件名是以.jpg或者.png结尾则认为是图片,可以自己添加其他格式的照片
if each.endswith('.jpg') or each.endswith('.png'):
i += 1
j += 1
# 拼接完整的包含路径的文件名
scr = os.path.join(dirpath, each)
# 拼接新的完整的包含路径的文件名, tail是文件夹的名字
dst = os.path.join(dirpath, tail + '-' + str(i) + '.jpg')
try:
# 重命名图片文件
os.rename(scr, dst)
print(scr + '--->' + dst)
except:
continue
else:
continue
print('累计重命名{}张图片'.format(j))
if __name__ == '__main__':
# 设置起始路径path
path = r'C:\Users\Jock\Desktop\手机'
# 创建实例对象
pics = BatchRenamePics(path)
# 调用实例方法
pics.rename()
输出:
C:\Users\Jock\Desktop\手机\1\1\10aeafb51acf7b6d7.jpg--->C:\Users\Jock\Desktop\手机\1\1\1-1.jpg
C:\Users\Jock\Desktop\手机\1\1\11a3ea555d8ca7e8b.jpg--->C:\Users\Jock\Desktop\手机\1\1\1-2.jpg
C:\Users\Jock\Desktop\手机\1\1\1c522c2da3c36757a.jpg--->C:\Users\Jock\Desktop\手机\1\1\1-3.jpg
...
C:\Users\Jock\Desktop\手机\9\9\1b9b78195adbb4bc4.jpg--->C:\Users\Jock\Desktop\手机\9\9\9-7.jpg
C:\Users\Jock\Desktop\手机\9\9\1ba3c0a1d956429e2.jpg--->C:\Users\Jock\Desktop\手机\9\9\9-8.jpg
C:\Users\Jock\Desktop\手机\9\9\1c16e93d0bf77a31f.jpg--->C:\Users\Jock\Desktop\手机\9\9\9-9.jpg
累计重命名910张图片
不到20s就搞定了。
看一下效果:
非常完美。
2.5 程序的扩展
这个程序还是用处很多的,稍微改编一下就可以用了,比如寻找目录下所有后缀是XXX的文件等等。
3. 参考文献
- Python os.walk的用法与举例
- python 对图片或者文本实现批量重命名
- Python os.rename()和os.renames()用法的区别
- Python os和os.path模块常用方法小结
后记:
我从本硕药学零基础转行计算机,自学路上,走过很多弯路,也庆幸自己喜欢记笔记,把知识点进行总结,帮助自己成功实现转行。
2020下半年进入职场,深感自己的不足,所以2021年给自己定了个计划,每日学一技,日积月累,厚积薄发。
如果你想和我一起交流学习,欢迎大家关注我的微信公众号每日学一技
,扫描下方二维码或者搜索每日学一技
关注。
这个公众号主要是分享和记录自己每日的技术学习,不定期整理子类分享,主要涉及 C – > Python – > Java,计算机基础知识,机器学习,职场技能等,简单说就是一句话,成长的见证!