os.walk help

Robin Munn rmunn at pobox.com
Mon Nov 24 19:10:03 CET 2003

hokiegal99 <hokiegal99 at hotmail.com> wrote:
> Thanks for the tip. That code shows all of the dirs that Python is 
> complaining about not in the list... trouble is, they *are* in the list. 
> Go figure. I'd like to try doing the rename outside the scope of 
> os.walk, but I don't undersdtand how to do this, when I break out of 
> os.walk and try the rename at a parallel level, Python complains that 
> variables such as "oldpath" and "newpath" are undefined.

Wait, I just realized that you're changing the list *while* you're
iterating over it. That's a bad idea. See the warning at the bottom of
this page in the language reference:


Instead of modifying the list while you're looping over it, use the
topdown argument to os.walk to build the tree from the bottom up instead
of from the top down. That way you won't have to futz with the dirnames
list at all:

    def clean_names(rootpath):
        bad = re.compile(r'%2f|%25|%20|[*?<>/\|\\]')
        for root, dirs, files in os.walk(rootpath, topdown=False):
            for dname in dirs:
                newdname = re.sub(bad, '-', dname)
                if newdname != dname:
                    newpath = os.path.join(root, newdname)
                    oldpath = os.path.join(root, dname)
                    os.renames(oldpath, newpath)

Notice also the use of re.sub to do all the character substitutions at
once. Your code as written would have failed on a filename like "foo*?",
since it always renamed from the original filename: it would have first
done os.renames("foo*?", "foo-?") followed by os.renames("foo*?",
"foo--") and the second would have raised an OSError.

Robin Munn
rmunn at pobox.com

More information about the Python-list mailing list