How to change folder names in python?
Asked Answered
A

7

55

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.

Atalee answered 4/1, 2012 at 22:56 Comment(0)
U
52

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))
Unicef answered 4/1, 2012 at 23:2 Comment(8)
When i tried this i'm told "The system cannot find the path specified: 'C:/Test/*.*' ". Not sure what this means.Atalee
@Atalee That means that C:/Test does not exist on your system. Are you sure that that's the directory where your user name directories lie in?Unicef
That means c:\Test is completely non-existent.Emotion
I have been using the code for other folders, and i have got this error for some folders: [Error 183] Cannot create a file when that file already exist. This is just because some folders already contain both the corect name and the uncorrected name. I want to just merge these folders. Would it work if i just added another if into the code, so that if the folder already exists then merge their contents?Atalee
@Unicef I've tried adding an 'if' at the end of the code and using os.path.join. I think this is the right way of going about it but i'm not sure how to write the if when the folder name is being changed to something that already exists.Atalee
@Atalee Well, your if should be before os.rename, and if it hits, you should skip the entry (i.e. continue). The whole code looks like: if os.path.exists(os.path.join(basedir, surname + ', ' + firstname)): continueUnicef
@Unicef This seems to just skip over this folder if the correct folder name already exists, instead of merging the folders which is what i would what.Atalee
@Atalee Oh, right. Sorry. You then want something like if os.path.exists(os.path.join(basedir, surname + ', ' + firstname)): mergeFolders(os.path.join(basedir, fn), os.path.join(basedir, surname + ', ' + firstname))Unicef
E
38
os.rename("Joe Blow", "Blow, Joe")

Seems to work fine for me. Which part are you having trouble with?

Emotion answered 4/1, 2012 at 23:1 Comment(5)
This is fine when i do it individually for each folder, but i couldn't seem to make it work for a loop through all the folders. The problem is i don't know how to specify first names and the surnames for all the folders.Atalee
phihag's example above will probably work perfectly. He uses the rnpartition to split the string. I probably would've just used split(), but his example should work.Emotion
can only be used for not empty folderAntiphon
That's not true... This works regardless of whether the folder is empty or not.Emotion
Well then it's at least true that sometimes os.rename() doesn't work and the error message contains a reference to emptiness or lack thereof. For those receiving an error something like OSError: [Errno 66] Directory not empty: in macOS, this may work instead https://mcmap.net/q/333320/-how-to-change-folder-names-in-pythonKamala
N
17

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")

Differences:

  1. 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.
  2. 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.

  3. 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.

  4. 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)


Norine answered 2/6, 2020 at 14:19 Comment(1)
The explanation is bonus. Gives you a comparison and optionsTranquillity
C
7

You can just put it in one command, with the full paths.

import os
os.rename("/path/old_folder_name", "/path/new_folder_name")
Coordinate answered 5/8, 2021 at 19:2 Comment(0)
S
3

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']
Saladin answered 4/1, 2012 at 23:46 Comment(0)
P
1
  1. os.rename at times fails to work.

  2. To ensure it renames the folders, apply os.chdir.

  3. In the example below, we are changing the subdirectories' names found in the main folder

     main_folder=r"C:\Users\clipped_features"
     path_file=os.listdir(main_folder)
    
     for i in range(len(path_file):
      #apply os.chdir before renaming
      os.chdir(main_folder)
      os.rename(os.path.join(main_folder,path_file[i],"new_name")
    
Polymath answered 6/6, 2023 at 9:10 Comment(0)
C
0

Nowadays it's worth considering using pathlib for tasks such as this. Example folder

We have your three folders plus one with a comma in its name. There is also the Python script that will rename these.

from pathlib import Path

for path in Path('.').glob('**'):
    
    path_as_str = str(path)
    
    # It's necessary to eliminate the current folder, denoted by '.', as well
    # as names already processed, which contain commas
    
    if path_as_str == '.' or ',' in path_as_str :
        continue
        
    #Find the blank preceding the surname in the input
    
    p = path_as_str.rfind(' ')
    new_name = f'{path_as_str[1+p:]}, {path_as_str[:p]}'

    # The essential part
    path.rename(new_name)
Cleveite answered 9/7, 2024 at 17:44 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.