discipline discipline - 28 days ago 5
Python Question

Rename directory's recursively in Python

I have a directory like this:

enter image description here

I encounter the problem that when using this function:

from os import walk
generic_name = "{project_name}"

def rename_project(src):
project_name = raw_input("Name your project: ")
for subdir, dirs, files in walk(src):
rename(subdir, subdir.replace(generic_name, project_name))


On reaching the second folder, i.e.
{project_name} Planning
the whole directory has been altered. i.e. has become:

enter image description here

And as such it appears the
for ... in walk(src):
ceases to run. Note that the loop is working correctly; I can print each directory and get the results:

for subdir, dirs, files in walk(src):
print subdir


yields...

enter image description here

With my limited knowledge of Python I assume that because the directory has been changed, this causes an exception to
walk(src)
and means that the loop is killed.

How can I work around this to recursively loop through the directory and rename all dirs that contain
{project_name}
?

Much thanks :)

Answer

Ether check the topdown parameter of the walk method for an iterative approach or use recursion to recursively traverse the directory tree.

Edit: Ok i do not know an elegant solution to rename the last occurance of a string, but here you go. ;)

import os
generic_name = "{project_name}"

subdirs = []

def rename_project(src):
    project_name = raw_input("Name your project: ")
    for subdir, dirs, files in os.walk(src,topdown=False):
        subdirs.append(subdir)

    for subdir in subdirs:
        newdir =  subdir[::-1].replace(generic_name[::-1], project_name[::-1], 1)[::-1]
        print newdir
        #os.rename(subdir,newdir)

rename_project(".")

I seperated collecting the dirs and renaming (or printing ^^) them. But you can see (if you run it) that it renames (prints) recursively starting in the inner most folder.

And i stole the "replace-last-occurance-in-string" from Mark Byers here How to replace the last occurence of an expression in a string. ^^

And the more clean, exception free, maybe harder to debug bonus version:

import os
generic_name = "{project_name}"

def rename_project(src):
    project_name = raw_input("Name your project: ")
    for subdir, dirs, files in os.walk(src,topdown=False):
        newdir =  subdir[::-1].replace(generic_name[::-1], project_name[::-1], 1)[::-1]
        print newdir
        if newdir != '.':
            os.rename(subdir,newdir)

rename_project(".")