Rename in bulk using the os module and glob module.
Use the os module and glob module to change and rename the file names in a folder in bulk by adding strings or sequential numbers before and after the file names.
Example file structure
Take the following file structure as an example. In this case, it is assumed that there are only files (no folders) in the folder.
. └── testdir ├── a.jpg ├── b.jpg ├── c.jpg ├── d.jpg └── e.jpg
Things to keep in mind
Since the process involves renaming the file, save the original file separately so that it can be saved in case of failure.
Get the file list with the glob module
The glob module will find all pathnames that match the specified pattern according to the rules used by the Unix shell.
glob — Unix style pathname pattern expansion — Python 3.10.0 Documentation
For example, the following function can be used to get a list of file and directory names in the current directory.glob.glob('./*')
The argument can be an absolute path or a relative path.
In this example, it would look like the following.
import glob print(glob.glob('./testdir/*')) # => ['./testdir/a.jpg', './testdir/b.jpg', './testdir/c.jpg', './testdir/d.jpg', './testdir/e.jpg']
Instead of a.jpg, you can get the following, with the argument path added../testdir/a.jpg
You can also use wildcards (*) to get only specific extensions, as shown below.glob.glob('./testdir/*.jpg')
The following pattern matching can be used.
*
: Matches everything.?
Matches any single character.[abc]
: Matches a single character from a, b, or c.[!abc]
: Matches a single character other than a, b, or c
Rename with os.rename()
os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)
Rename the file or directory src to dst.
os — Miscellaneous operating system interfaces — Python 3.10.0 Documentation
Use the function rename() of the os module, which will rename it as the name suggests.
import os os.rename('./testdir/a.jpg', './testdir/a_000.jpg')
Then, a.jpg will be renamed to a_000.jpg.
Generating zero-filled sequential numbers with str.format()
For example, when adding sequential numbers to dozens of files, we want to use “00” or “11” instead of “0” or “1”. If you want to fill in the zeros in this way, use the str.format() method.
str.format(args,*kwargs)
Performs string formatting operations. The string that invokes this method can contain normal characters or substitution fields separated by {}.Built-in Types — Python 3.10.0 Documentation
Syntax of format specification strings
The formatting string contains the “replacement field” enclosed in curly brackets {}.The syntax of the replacement field is as follows:
replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"
In simpler terms, the replacement field starts with field_name, which causes the value of the specified object to be formatted and inserted into the output instead of the replacement field. After the field_name, the conversion field can be followed by an exclamation mark '! After the field_name, the conversion field can be followed by an exclamation mark '! The format_spec can be written with a colon ':' at the end. This specifies the non-default format of the value to be replaced.
string — Common string operations — Python 3.10.0 Documentation
If you want to fill it with 0 for now, do the following.
# 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
Example of code to add a string/sequential number before a file
First, get the file name with os.path.basename(). Then, add a string or sequential number in front of the file name, and concatenate it with the original path with os.path.join().
The following example adds img_ to the front of all file names.
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)))
The result is as follows.
. └── testdir ├── img_a.jpg ├── img_b.jpg ├── img_c.jpg ├── img_d.jpg └── img_e.jpg
If you want to add sequential numbers, change the for statement to something like this: enumerate() to get the numbers counted in order from 0. In this case, the number is filled with three digits.
for i, f in enumerate(files): os.rename(f, os.path.join(path, '{0:03d}'.format(i) + '_' + os.path.basename(f)))
Here's the result.
. └── testdir ├── 000_a.jpg ├── 001_b.jpg ├── 002_c.jpg ├── 003_d.jpg └── 004_e.jpg
If you want to start with 1 instead of 0, set the second argument of enumerate to 1.
for i, f in enumerate(files, 1): os.rename(f, os.path.join(path, '{0:03d}'.format(i) + '_' + os.path.basename(f)))
It goes like this.
. └── testdir ├── 001_a.jpg ├── 002_b.jpg ├── 003_c.jpg ├── 004_d.jpg └── 005_e.jpg
Example of code to add a string/sequential number after a file
Use os.path.splitext() to split the file into extension and root path, and then add strings or sequential numbers to the root path. In the following example, _img is added after all file names.
import os import glob files = glob.glob('./testdir/*') for f in files: ftitle, fext = os.path.splitext(f) os.rename(f, ftitle + '_img' + fext)
The result is this.
. └── testdir ├── a_img.jpg ├── b_img.jpg ├── c_img.jpg ├── d_img.jpg └── e_img.jpg
As with adding a string/sequential number before a file, change the for statement when adding a sequential number.
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