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 文件遍历的方法

  1. os.scandir(path='.'),Python3.5后提供,通过减少os.stat()调用提升速度,通常比os.listdir()快,返回一个包含path路径下所有目录和文件的迭代器。
  2. os.listdir(path='.'),返回一个包含path下所有目录和文件的列表.
  3. 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 文件重命名

  1. os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None),把src重命名为dst, 返回值为None,不支持跨平台。
  2. os.replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None), 把src重命名为dst, 返回值为None,支持跨平台.不过要慎用,因为如果dst存在则会被覆盖掉。会导致误删文件。建议用rename。
  3. os.renames(old, new),递归重命名src为dst。返回值为None。
    具体可以看我的另外一篇Python os.rename()和os.renames()用法的区别

其他的关于osos.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. 参考文献

  1. Python os.walk的用法与举例
  2. python 对图片或者文本实现批量重命名
  3. Python os.rename()和os.renames()用法的区别
  4. Python os和os.path模块常用方法小结
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页