Hi folks. First post here. I am looking for a python script to rename
files in a folder based on various rules. I have a VBA version that
works but it’s slow and I want to scale this up, and I think python
might be the right tool for the job.
Is it okay to post this kind of request here? Please delete if not, but read on if you are able to help.
Sure. But because we don’t do homework (which this may not be) and in
order to help you learn, we won’t write the whole script. We’ll help you
with suggestions and address queries.
All the Python functions and modules mentioned below are described in
the Python documentation:
https://docs.python.org/3/
Have that open. Both the “modules” and “index” pages are particularly
useful for finding things.
All files will be in a single folder and there are three different file types.
- PDF. These just need renamed by removing and reordering some parts of the existing name
- Invoice header csv. These need to be renamed using the invoice number which is inside the file. The file is csv format with quotes around strings. The invoice number is in row 2 column six and the file needs renamed as invoicenumber-header.csv
- Invoice details csv. Same as above. The invoice number is in row 2
column six and the file needs to be renamed as
invoicenumber-details.csv
Suggestion 1: give your script a “no action” mode. Renaming files can be
destructive when you make mistakes, so have the no action mode just
print the suggested change. Later, apply the change (by changing modes):
import os
from os.apth import eixsts
# change this later, maybe with a command line option
doit = False
def rename_file(filename, doit):
... decide what the new name should be based on your rules ...
if new_filename != filename:
print("rename", filename, "=>", new_filename)
if exists(new_filename):
print("new filename already exists, rejecting!")
elif doit:
os.rename(filename, new_filename)
The easiest way to read a single folder is os.listdir:
import os
foldername = 'your-folder'here'
for filename in os.listdir(foldername):
... process the filename ...
Note that you get the bare names from listdir, do the actual filename
will be foldername/filename:
from os.path import join
real_filename = join(folder_name, filename)
but for ease of running your rules you probably want to work against the
filename itself. Then add in the foldername when you decide to do the
rename (since it will need the real pathname).
There’s a useful method in os.path called splitext:
from os.path import splitext
filebase, ext = splitext(filename)
After that, ext will be ‘.csv’ or whatever. filebase will be the part
before the file extension.
Start with that and make a little script, then come back with questions.
You may find the “re” module useful for matching what’s in filebase.
Finally, you sound like you’re using Windows. In Windows the path
separator is the backslash (‘\’). Which is also special in Python
strings. So use “raw” strings when writing literal Windows paths because
of the conflict:
foldername = r'C:\Users\blah\this\that'
Do the same with regular expressing (in the 're" module) because
backslashes are special in those, too.
Cheers,
Cameron Simpson cs@cskk.id.au