How to change folder names in python?
Question:
I have multiple folders each with the name of a person, with the first name(s) first and the surname last. I want to change the folder names so that the surname is first followed by a comma and then the first name(s) follow.
As an example, in the folder Test, i have:
C:/Test/John Smith
C:/Test/Fred Jones
C:/Test/Ben Jack Martin
and i want to make this:
C:/Test/Smith, John
C:/Test/Jones, Fred
C:/Test/Martin, Ben Jack
I tried some things with os.rename but i couldn’t seem to make it work with the varying name length, and i wasn’t sure how to insert the comma into the surname.
Also, some of the folder names are already in the correct form, so i need to skip these folders during the renaming. I think you can do this by just adding an if, so that if the folder name contains a comma it will continue.
Otherwise, the surname will always be the last word in the folder name.
Thanks for any help you can provide.
Answers:
os.rename("Joe Blow", "Blow, Joe")
Seems to work fine for me. Which part are you having trouble with?
You can write it out fairly straight-forward, using os.listdir
and the os.path functions:
import os
basedir = 'C:/Test'
for fn in os.listdir(basedir):
if not os.path.isdir(os.path.join(basedir, fn)):
continue # Not a directory
if ',' in fn:
continue # Already in the correct form
if ' ' not in fn:
continue # Invalid format
firstname,_,surname = fn.rpartition(' ')
os.rename(os.path.join(basedir, fn),
os.path.join(basedir, surname + ', ' + firstname))
I like phihag’s suggestion of rpartition()
, I think the following are mostly equivalent:
>>> 'first second third fourth'.rpartition(' ')
('first second third', ' ', 'fourth')
>>> 'first second third fourth'.rsplit(None, 1)
['first second third', 'fourth']
I prefer rsplit()
because I don’t want to care about the separator, but I can also see that it is a bit more verbose.
Setup
>>> base = 'C:\Test'
>>> os.makedirs(os.path.join(base, 'John Smith'))
>>> os.makedirs(os.path.join(base, 'Fred Jones'))
>>> os.makedirs(os.path.join(base, 'Ben Jack Martin'))
>>> os.listdir(base)
['Ben Jack Martin', 'Fred Jones', 'John Smith']
Solution
>>> for old_name in os.listdir(base):
# [::-1] is slice notation for "reverse"
new_name = ', '.join(old_name.rsplit(None, 1)[::-1])
os.rename(os.path.join(base, old_name),
os.path.join(base, new_name))
>>> os.listdir(base)
['Jones, Fred', 'Martin, Ben Jack', 'Smith, John']
An alternative to os.rename
is shutil.move(src, dest)
import shutil
import os
shutil.move("M://source/folder", "M://destination/folder")
os.rename("M://source/folder", "M://destination/folder")
- OS module might fail to move a file if the source and destination path is on different file systems or drive.
But shutil.move will not fail in this kind of cases.
-
shutil.move checks if the source and destination path are on the same file system or not. But os.rename does not check, thus it fails sometimes.
-
After checking the source and destination path, if it is found that they are not in the same file system, shutil.move will copy the file first to the destination. Then it will delete the file from the source file. Thus we can say shutil.move is a smarter method to move a file in Python when the source and destination path are not on the same drive or file system.
-
shutil.move works on high-level functions, while os.rename works on lower-level functions.
I would also advise using pathlib
to manipulate paths:
from shutil import move
from pathlib import Path
base_path = Path("C:/Test")
for folder in base_path.iterdir():
if not folder.is_dir() or folder.name.startswith("."):
continue
name = folder.name
new_name = ", ".join(name.split(" "))
new_folder = folder.parent / new_name
move(folder, new_folder)
You can just put it in one command, with the full paths.
import os
os.rename("/path/old_folder_name", "/path/new_folder_name")
I have multiple folders each with the name of a person, with the first name(s) first and the surname last. I want to change the folder names so that the surname is first followed by a comma and then the first name(s) follow.
As an example, in the folder Test, i have:
C:/Test/John Smith
C:/Test/Fred Jones
C:/Test/Ben Jack Martin
and i want to make this:
C:/Test/Smith, John
C:/Test/Jones, Fred
C:/Test/Martin, Ben Jack
I tried some things with os.rename but i couldn’t seem to make it work with the varying name length, and i wasn’t sure how to insert the comma into the surname.
Also, some of the folder names are already in the correct form, so i need to skip these folders during the renaming. I think you can do this by just adding an if, so that if the folder name contains a comma it will continue.
Otherwise, the surname will always be the last word in the folder name.
Thanks for any help you can provide.
os.rename("Joe Blow", "Blow, Joe")
Seems to work fine for me. Which part are you having trouble with?
You can write it out fairly straight-forward, using os.listdir
and the os.path functions:
import os
basedir = 'C:/Test'
for fn in os.listdir(basedir):
if not os.path.isdir(os.path.join(basedir, fn)):
continue # Not a directory
if ',' in fn:
continue # Already in the correct form
if ' ' not in fn:
continue # Invalid format
firstname,_,surname = fn.rpartition(' ')
os.rename(os.path.join(basedir, fn),
os.path.join(basedir, surname + ', ' + firstname))
I like phihag’s suggestion of rpartition()
, I think the following are mostly equivalent:
>>> 'first second third fourth'.rpartition(' ')
('first second third', ' ', 'fourth')
>>> 'first second third fourth'.rsplit(None, 1)
['first second third', 'fourth']
I prefer rsplit()
because I don’t want to care about the separator, but I can also see that it is a bit more verbose.
Setup
>>> base = 'C:\Test'
>>> os.makedirs(os.path.join(base, 'John Smith'))
>>> os.makedirs(os.path.join(base, 'Fred Jones'))
>>> os.makedirs(os.path.join(base, 'Ben Jack Martin'))
>>> os.listdir(base)
['Ben Jack Martin', 'Fred Jones', 'John Smith']
Solution
>>> for old_name in os.listdir(base):
# [::-1] is slice notation for "reverse"
new_name = ', '.join(old_name.rsplit(None, 1)[::-1])
os.rename(os.path.join(base, old_name),
os.path.join(base, new_name))
>>> os.listdir(base)
['Jones, Fred', 'Martin, Ben Jack', 'Smith, John']
An alternative to os.rename
is shutil.move(src, dest)
import shutil
import os
shutil.move("M://source/folder", "M://destination/folder")
os.rename("M://source/folder", "M://destination/folder")
- OS module might fail to move a file if the source and destination path is on different file systems or drive.
But shutil.move will not fail in this kind of cases.shutil.move checks if the source and destination path are on the same file system or not. But os.rename does not check, thus it fails sometimes.
After checking the source and destination path, if it is found that they are not in the same file system, shutil.move will copy the file first to the destination. Then it will delete the file from the source file. Thus we can say shutil.move is a smarter method to move a file in Python when the source and destination path are not on the same drive or file system.
shutil.move works on high-level functions, while os.rename works on lower-level functions.
I would also advise using pathlib
to manipulate paths:
from shutil import move
from pathlib import Path
base_path = Path("C:/Test")
for folder in base_path.iterdir():
if not folder.is_dir() or folder.name.startswith("."):
continue
name = folder.name
new_name = ", ".join(name.split(" "))
new_folder = folder.parent / new_name
move(folder, new_folder)
You can just put it in one command, with the full paths.
import os
os.rename("/path/old_folder_name", "/path/new_folder_name")