用Python写一个文件命名处理脚本

Aengus Sun 845 2019-04-12

写这个脚本主要是给自己用的,因为有时候在网上下载的资源每个文件前面都有一句广告,一个文件一个文件的重命名太慢,于是就写了这个脚本。Python的os模块封装了大量的系统命令,我们可以方便的调用。目前脚本有这几个功能:

  1. 将文件名称中指定的文字删掉
  2. 添加指定的文字到文件名称的前面
  3. 添加指定的文字到文件名称的后面
  4. 用输入的文字重命名某个文件夹下所有文件(格式:输入文字(n),n=1,2,3,...)
  5. 用新的文字替换掉某个文件夹下的特定文字
  6. 用文件的创建/修改/访问时间重命名某个文件夹下的所有文件(格式:年月日-时分秒)
  7. 按照输入的规则匹配“#”重命名文件

对于以上的功能,全部都需要文件夹的绝对路径,文件的重命名也是建立在绝对路径之上的,所以下面的函数返回的都是文件的绝对路径。

获取文件夹下所有文件

最主要的函数是得到某个文件夹下的所有文件,并将所有文件的绝对路径添加到list中。在此过程中会询问是否对文件夹进行操作,主要代码如下:

def get_all_files_path(dir_path):
    all_files = []
            while True:
            # ch: 是否重命名文件夹
            ch = input("是否对文件夹操作[Y/N]?\n")
            if ch == "Y" or ch == "y":
                for file_name in listdir(dir_path):
                    file_path = path.join(dir_path, file_name)
                    all_files.append(file_path)
                break
            elif ch == "N" or ch == "n":
                for file_name in listdir(dir_path):
                    file_path = path.join(dir_path, file_name)
                    # 如果是文件,就将其添加到list中
                    if path.isfile(file_path):
                        all_files.append(file_path)
                break
            else:
                print(out_input_error_cn)

    return all_files

其中os.listdir(path)是列出输入路径下的所有文件的名称,包括文件夹,因此还要用os.path.join()函数将输入的文件夹绝对路径与文件名称联合起来,这样才可以得到文件的绝对路径。

删除、添加和替换文字

对于文件名称的删除、添加或替换文字大同小异,这里以删除为例:

  1. 首先获取文件的名称,判断待删除的文字是否在其中;
  2. 然后获得文件的绝对路径(不包含文件名称,之后会将其与文件的新名称结合到一起);
  3. 获取文件类型,并将其从文件名称中去掉,比如"test.txt"去掉之后就变为了"test",这样做是为了防止删除的文字也包含在文件的类型名中;
  4. 将上一步得到的文件名删除掉特定的文字得到的新文件名;
  5. 将第2步得到的绝对路径、第3步得到的文件类型、第四步得到的文件名联合到一起
  6. 调用os.rename函数

代码如下:

# 当前文件名
file_name_now = os.path.basename(file_path)
# 不包含文件名的绝对路径即目录路径
file_abspath_no_name = os.path.dirname(file_path)
# 保存文件类型
file_type = os.path.splitext(file_path)[1]

# 将文件类型从文件名中去掉
file_name_deleted_type = file_name_now.replace(file_type, "")

# 将绝对路径、文件名、类型联合
file_name_new_no_type = file_name_deleted_type.replace(str_to_del, "")
file_name_new = file_name_new_no_type + file_type
file_name_final = os.path.join(file_abspath_no_name, file_name_new)

os.rename(file_path, file_name_final)

这里主要说一下第3步和第5步用到的函数。os.path.splitext(path)函数可以将文件路径与文件类型分割,返回一个tuple,我们就可以用切片操作符([ ])来得到文件类型,例如os.path.splitext('E:/test.txt')可以得到("E:/test",".txt"),还有一个类似的函数是os.path.split(path),返回的是包含文件的目录路径和文件名的tuple;和路径有关的字符串联合不能简单的用+,需要用到os.path.join函数。

重命名文件及添加后缀

重命名文件以及添加后缀实现都比较简单,在获得了文件的目录路径和新文件名后直接重命名即可,添加后缀只要设立一个变量累加并将其添加到文件名中即可。主要值得一提的是按照特定的顺序添加后缀,目前支持根据文件在资源浏览器中的顺序、创建时间、最近修改时间和最近访问时间来确定顺序。

由于在get_all_files_path()函数中我们已经得到的一个list,所以我们直接对其排序即可,如果不排序则其顺序就是文件在资源浏览器中的顺序。

os.path.getctime(path)    # 获得文件创建时间
os.path.getmtime(path)    # 获得文件最近修改时间
os.path.getatime(path)    # 获得文件最近访问时间

对于list的排序我们需要用到lambda表达式:

new_list = sorted(get_all_files_path(dir_path), key=lambda file_p: os.path.getctime(file_p))

lambda表达式等同于下面的表达方式:

lambda x: x + x

def function(x):
    return x + x

用文件创建/修改/访问时间重命名文件

以文件创建时间为例:
首先获取文件创建时间,和上面用到的函数一样,获得的是一串浮点数,我们要将其转化为时间的格式,用到函数time.localtime(time),这个函数是将得到的浮点数转化成当地时间,之后我们再格式化即可:

file_time = path.getctime(file_path)    # 获取文件创建时间
file_localtime = time.localtime(file_time)    # 转化成当地时间
file_time_format = time.strftime("%Y%m%d-%H%M%S", file_localtime)    # 格式化

得到的格式为“年月日-时分秒”

PS: 最终采取的并不是这种格式,虽然精准但是比较乱,所以采用了和“用输入的文字重命名某个文件夹下所有文件”类似的格式,得到的格式是“年月日-1/2/...”,实现麻烦些速度也慢,但是更规范一些

其他

Python对系统命令的封装使得用Python写一个类似的脚本变得很简单,当我打算用C/C++重写时在获得某个文件夹下的所有文件时就遇到了困难......

在调用import的模块的函数时,解释器会先搜索这个模块中所有的函数,这样就会增加一定的时间开销,所以在大量调用某个模块中的一个函数时,用from ... import ...会更快些;

利用函数os.getcwd()可以获取当前脚本所在文件夹路径,这样就可以很方便的将脚本复制到某个文件夹后直接对当前文件夹操作;为了防止在重命名过程中操作脚本,需要将get_all_files_path()函数获得的list去掉脚本的路径,利用os.path.realpath(__file__)可以获得当前运行的py文件的路径,有关的更多信息可以查看这篇博客:python获取当前路径

源代码地址

(本博客创建于2019-03-30)