-3

I use the following code to replace file/folder names in a directory.

old = abc
new = def

for path, subdirs, files in os.walk(folder_path):
    for name in files:
        if old in name:
            file_path = os.path.join(path, name)
            new_name = os.path.join(path, name.replace(old, new))
            os.rename(file_path, new_name)

This works, however, I have one folder named abc.files os.walk does not see this folder, how do I fix the code so it changes abc.files to def.files ?

Barmar
  • 741,623
  • 53
  • 500
  • 612
Spatial Digger
  • 1,883
  • 1
  • 19
  • 37
  • 4
    If `abc.files` is a subdir, then it will be in the `subdirs` list, not the `files` list. You're only iterating over `files`. – John Gordon Oct 20 '21 at 22:34
  • 1
    Also, `new = def` is an error. Did you mean `new = "def"`? – John Gordon Oct 20 '21 at 22:34
  • 1
    If you rename directories while walking, you should use `topdown=False` so it will walk into the subdirectory before it renames it. – Barmar Oct 20 '21 at 22:38

1 Answers1

3

As mentioned in a comment, you're only renaming files, not subdirectories, because you're not looping over the subdirs list. Try this:

for path, subdirs, files in os.walk(folder_path, topdown=False):
    for name in files + subdirs:
        if old in name:
            file_path = os.path.join(path, name)
            new_name = os.path.join(path, name.replace(old, new))
            os.rename(file_path, new_name)

topdown = False ensures that it will walk into a subdirectory before it's renamed.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • you help me understand better about `os.walk()`; `for name in filter(lambda x: x and old in x, files + subdirs)` so u no need to `if old in name` – lam vu Nguyen Apr 13 '23 at 08:02
  • 1
    They're equivalent, but I think most people find the `if` statement easier to read. – Barmar Apr 13 '23 at 14:58