在Python中通过在文件名前后添加字符串或连续的数字来批量改变一个文件名

商业

使用os模块和glob模块进行批量重命名。

使用os模块和glob模块,通过在文件名前后添加字符串或连续的数字来批量改变和重命名一个文件夹中的文件名。

文件结构示例

以下面的文件结构为例。在这种情况下,假定文件夹中只有文件(没有文件夹)。

.
└── testdir
    ├── a.jpg
    ├── b.jpg
    ├── c.jpg
    ├── d.jpg
    └── e.jpg

需要记住的事情

由于这个过程涉及到重命名文件,所以要单独保存原始文件,以便在失败时可以保存。

用glob模块获取文件列表

glob模块将根据Unix shell使用的规则找到所有符合指定模式的路径名。
glob — Unix style pathname pattern expansion — Python 3.10.0 Documentation

例如,以下函数可以用来获取当前目录中的文件和目录名称的列表。
glob.glob('./*')
参数可以是一个绝对路径,也可以是一个相对路径。

在这个例子中,它看起来像下面这样。

import glob

print(glob.glob('./testdir/*'))
# => ['./testdir/a.jpg', './testdir/b.jpg', './testdir/c.jpg', './testdir/d.jpg', './testdir/e.jpg']

而不是a.jpg,你可以得到以下结果,并添加了参数路径。
./testdir/a.jpg

你也可以使用通配符(*),只获得特定的扩展名,如下所示。
glob.glob('./testdir/*.jpg')

可以使用以下模式匹配。

  • *: 匹配一切。
  • ?匹配任何单一字符。
  • [abc]: 匹配a,b,或c中的单个字符。
  • [!abc]: 匹配除a、b或c以外的单个字符

用os.rename()重命名

os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)
将文件或目录src重命名为dst。
os — Miscellaneous operating system interfaces — Python 3.10.0 Documentation

使用os模块的函数rename(),它将如其名所示重命名。

import os
os.rename('./testdir/a.jpg', './testdir/a_000.jpg')

然后,a.jpg将被重命名为a_000.jpg。

用str.format()生成零填充的连续数字

例如,在给几十个文件添加顺序号时,我们想用 “00 “或 “11 “而不是 “0 “或 “1”。如果你想以这种方式填入零,请使用str.format()方法。

str.format(args,*kwargs)
执行字符串格式化操作。调用此方法的字符串可以包含正常字符或由{}分隔的替换字段。Built-in Types — Python 3.10.0 Documentation

格式规范字符串的语法
格式化字符串包含 “替换字段”,用大括号{}括起来。

替换字段的语法如下。
replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"

更简单地说,转换字段以field_name开始,它使指定对象的值被格式化并插入到输出中,而不是转换字段。在field_name之后,转换字段可以用感叹号'!在field_name之后,转换字段可以用感叹号'! format_spec可以用冒号':'写在最后。这指定了要被替换的值的非默认格式。
string — Common string operations — Python 3.10.0 Documentation

如果你想暂时把它填成0,请做以下工作。

# 3を2桁でゼロ埋め
print('{0:02d}'.format(3))
# => 03

# Fill in the zeros with three and four digits for 4 and 6, respectively.
print('{0:03d}, {1:04d}'.format(4, 6))
# => 004, 0006

在文件前添加一个字符串/顺序号的代码示例

首先,用os.path.basename()获取文件名。然后,在文件名前面添加一个字符串或顺序号,用os.path.join()将其与原始路径连接起来。

下面的例子在所有文件名的前面加上了img_。

import os
import glob

path = "./testdir"
files = glob.glob(path + '/*')

for f in files:
    os.rename(f, os.path.join(path, 'img_' + os.path.basename(f)))

结果如下。

.
└── testdir
    ├── img_a.jpg
    ├── img_b.jpg
    ├── img_c.jpg
    ├── img_d.jpg
    └── img_e.jpg

如果你想添加连续的数字,把for语句改成这样:enumerate()获得从0开始依次计数的数字,在这种情况下,数字被填上三位数。

for i, f in enumerate(files):
    os.rename(f, os.path.join(path, '{0:03d}'.format(i) +
                              '_' + os.path.basename(f)))

结果是这样的。

.
└── testdir
    ├── 000_a.jpg
    ├── 001_b.jpg
    ├── 002_c.jpg
    ├── 003_d.jpg
    └── 004_e.jpg

如果你想从1而不是0开始,就把enumerate的第二个参数设为1。

for i, f in enumerate(files, 1):
    os.rename(f, os.path.join(path, '{0:03d}'.format(i) +
                              '_' + os.path.basename(f)))

它是这样的。

.
└── testdir
    ├── 001_a.jpg
    ├── 002_b.jpg
    ├── 003_c.jpg
    ├── 004_d.jpg
    └── 005_e.jpg

在文件后添加一个字符串/顺序号的代码示例

使用os.path.splitext()将文件分割成扩展名和根路径,然后在根路径上添加字符串或连续的数字。在下面的例子中,_img被加在所有文件名后面。

import os
import glob

files = glob.glob('./testdir/*')

for f in files:
    ftitle, fext = os.path.splitext(f)
    os.rename(f, ftitle + '_img' + fext)

其结果是这样的。

.
└── testdir
    ├── a_img.jpg
    ├── b_img.jpg
    ├── c_img.jpg
    ├── d_img.jpg
    └── e_img.jpg

与在文件前添加字符串/顺序号一样,在添加顺序号时要改变for语句。

for i, f in enumerate(files):
    ftitle, fext = os.path.splitext(f)
    os.rename(f, ftitle + '_' + '{0:03d}'.format(i) + fext)
.
└── testdir
    ├── a_000.jpg
    ├── b_001.jpg
    ├── c_002.jpg
    ├── d_003.jpg
    └── e_004.jpg