Python批量重命名文件示例(带演示功能)

<pre name="code" class="python">''' Created on 2015-9-17

@author: liuhaifeng
@module: rename
@note: rename files in a Windows system

删除文件名中指定的前缀或后缀字符 小工具:
       用法介绍:
         [参数1] 文件目录
         [参数2] 需要删除的字符
         [参数3(可选)] [指定要处理的文件的扩展名(如果为空将处理所有文件)]
         example:
         如下文件:
         "D:\Demo\0001.凤凰宽频-2015-08-21锵锵三人行 梁文道:民间谣言被证实将损害政府公信力.mp4"
         "D:\Demo\0001.凤凰宽频-2015-08-24锵锵三人行 人民币的贬值有一个最根本原因.mp4"
         "D:\Demo\0001.凤凰宽频-2015-08-27锵锵三人行 窦文涛:《三体》开篇写文革 赞作者想象力.mp4"

         想要去除每个文件前面的"0001.凤凰宽频-2015-08-24锵锵三人行 "字符,
         可输入如下参数:

         注意: 每个参数务必都要用双引号包起来
         "D:\Demo" "0001.凤凰宽频-2015-08-24锵锵三人行 " ".mp4"

 为防止误操作, 导致无意删除后无法撤销的问题, 在执行"重命名"操作之前, 本程序提供"重命名"演示功能, 
 会将"重命名"之前和"重命名"之后的文件列表打印出来, 供用户参考, 如果觉得没有什么问题, 就可以"确定"
 执行"重命名", 如果发现不妥, 还有反悔的可能。

 本来打算利用sqlite数据库,实现一个支持"重命名"后,如果后悔,可以"回滚"的版本,但目前没有想
 好怎么实现, 有兴趣的读者可以考虑考虑,如果你有好的想法或实现,麻烦告知,不胜感谢!
@email: liuhhaiffeng@163.com

'''

import os
import sys
import re

#//
# 实战
#//

# 删除文件名中指定的前缀或后缀字符
def reChangeFileName(dirPath,       # 文件所有的文件夹路径
                remStr,             # 需要删除的字段
                extName=None        # 指定扩展名的文件, 不指定则对所有文件生效                    
                ):
    log = []
    fileNames = os.listdir(dirPath)
    # 根据扩展名过滤文件列表
    if extName is not None:
        fileNames = filterFileNames_ByExt(fileNames, extName)
    # 根据是否存在要删除的字符进一步过滤文件列表
    fileNames = filterFileNames_ByRemStr(fileNames, remStr)
    for fileName in fileNames:
        # 进行文件"重命名"
        myRename(dirPath, fileName, remStr)
        # 输出日志
        log.append(fileName)
    return log

# 返回符合指定扩展名的文件列表
def filterFileNames_ByExt(fileNames, extName):
    names = []    
    for fileName in fileNames:
        if fileName.endswith(extName):
            names.append(fileName)
    return names

# 返回包含要删除字符的文件列表
def filterFileNames_ByRemStr(fileNames, remStr):
    names = []
    for fileName in fileNames:
        fileNameNoExt = os.path.splitext(fileName)[0]
        # 如果文件名与remStr相同, 也要过滤掉        
        tmpName = fileNameNoExt.strip(remStr)
        tmpLen = len(tmpName)
        # 若 tmpLen == len(fileNameNoExt), 说明文件名与remStr相同, 对此种情况不进行重命名
        # (因为重命名后,也不会出错,只是文件名为空,没有实际意义);
        # 若 tmpLen < len(fileNameNoExt) and tmpLen > 0, 说明文件名前缀或后缀包含remStr;
        # 若 tmpLen == 0, 说明文件名前缀或后缀中没有remStr;
        if tmpLen < len(fileNameNoExt) and tmpLen > 0:
            names.append(fileName)
    return names   
    

def  myRename(dirPath, fileName, remStr):
    sufix = os.path.splitext(fileName)
    fileNameNoExt = sufix[0]        # 文件名(没有扩展名及.号)
    extNameWithDot = sufix[1]       # 扩展名包含.号
    # 希望只删除文件名(不包括扩展名)中的前缀和后缀字符
    dstFileNameNoExt = fileNameNoExt.strip(remStr)           
    dstFileName = dstFileNameNoExt + extNameWithDot
    os.rename(os.path.join(dirPath, fileName), os.path.join(dirPath, dstFileName))


#//
# 演示, 仅供用户查看"重命名"效果
#//

# 删除文件名中指定的前缀或后缀字符
def reChangeFileName_OnlyDemo(dirPath,       # 文件所有的文件夹路径
                remStr,                      # 需要删除的字段
                extName=None                 # 指定扩展名的文件, 不指定则对所有文件生效                    
                ):    
    log = []
    fileNames = os.listdir(dirPath)
    # 根据扩展名过滤文件列表
    if extName is not None:
        fileNames = filterFileNames_ByExt(fileNames, extName)
    fileNames = filterFileNames_ByRemStr(fileNames, remStr)
    for fileName in fileNames:         
        log.append(myRename_OnlyDemo(dirPath, fileName, remStr))        
    return log

def myRename_OnlyDemo(dirPath, fileName, remStr):    
    sufix = os.path.splitext(fileName)
    fileNameNoExt = sufix[0]        # 文件名(没有扩展名及.号)
    extNameWithDot = sufix[1]       # 扩展名包含.号
    # 希望只删除文件名(不包括扩展名)中的前缀和后缀字符
    dstFileNameNoExt = fileNameNoExt.strip(remStr)           
    dstFileName = dstFileNameNoExt + extNameWithDot    
    return (fileName, dstFileName)

def printOnlyDemo(log):
    print('修改日志: 重命名文件总数为: %d' % len(log))
    print('重命名演示如下:')
    idx = 0
    for i, line in enumerate(log, 1):
        idx += 1
        print('[%d] [%s] %s' % (idx, 'x', line[0]))
        idx += 1
        print('[%d] [%s] %s' % (idx, 'y', line[1]))

def printLog(log):
    print('修改日志: 重命名文件总数为: %d' % len(log))
    for i, line in enumerate(log, 1):
        print('[%d] %s' % (i, line))
    
    
        

if __name__ == '__main__':
    print('''
       删除文件名中指定的前缀或后缀字符 小工具:
       用法介绍:
         [参数1] 文件目录
         [参数2] 需要删除的字符
         [参数3(可选)] [指定要处理的文件的扩展名(如果为空将处理所有文件)]
         example:
         如下文件:
         "D:\Demo\0001.凤凰宽频-2015-08-21锵锵三人行 梁文道:民间谣言被证实将损害政府公信力.mp4"
         "D:\Demo\0001.凤凰宽频-2015-08-24锵锵三人行 人民币的贬值有一个最根本原因.mp4"
         "D:\Demo\0001.凤凰宽频-2015-08-27锵锵三人行 窦文涛:《三体》开篇写文革 赞作者想象力.mp4"

         想要去除每个文件前面的"0001.凤凰宽频-2015-08-24锵锵三人行 "字符,
         可输入如下参数:

         注意: 每个参数务必都要用双引号包起来
         "D:\Demo" "0001.凤凰宽频-2015-08-24锵锵三人行 " ".mp4"
    ''')
    usrInput = input("请输入参数:\n")

    # 用户输入参数检查
    #++++++++++++++++++++++++++++++++
    dirPath = ''
    remStr = ''
    ext = ''
    parameters = re.findall(r'"(.*?)"', usrInput)       
    #print("len is %d" % len(parameters))   
    if len(parameters) == 3:
        dirPath, remStr, ext = parameters         
    elif len(parameters) == 2:
        dirPath, remStr = parameters        
        ext = None
    else:
        print("输入的参数个数不正确, 程序退出!")
        sys.exit()
    #--------------------------------

    #+++++++++++++++++++++++++++++++++
    isDemo = input("在重命名之前是否先要演示一遍 y/n?\n")
    if isDemo == 'y' or isDemo == 'Y':
        log = reChangeFileName_OnlyDemo(dirPath, remStr, ext)
        printOnlyDemo(log)
        isExec = input("是否要开始实战y/n?\n")
        if isExec == 'y' or isExec == 'Y':
            log = reChangeFileName(dirPath, remStr, ext)
            printLog(log)
        else:
            print("程序退出!")            
    else:
        log = reChangeFileName(dirPath, remStr, ext)
        printLog(log)
    #---------------------------------
    
                




 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值