Search code examples
pythonpython-3.xrenamefile-renamebatch-rename

os.rename does not succeed in renaming in subdirectories, throws FileNotFoundError despite using glob.glob with recursive=True


The following code is meant to rename files named "notes" to "notes.html.pmd" in the cwd and in sub-directories. Those still on Python3.7 and earlier versions need to get rid off the walrus operator and substitute

fileListOld = glob.glob(f"{(cwd := os.getcwd())}/**/{old_name}", recursive=True)

with

cwd = os.getcwd()
fileListOld = glob.glob(f"{cwd}/**/{old_name}", recursive=True)

in order to run this code. Anyways, the code is following:

#!/usr/bin/env python3.8

import glob, os

old_name = r"notes"

new_name = r"notes.html.pmd"

fileListOld = glob.glob(f"{(cwd := os.getcwd())}/**/{old_name}", recursive=True)
print(fileListOld)

for f in fileListOld:
    os.rename(old_name, new_name)

The issue is that renames "notes" only in CWD and not in sub-directories. Moreover Python throws the following error:

Traceback (most recent call last):
  File "./rename.py", line 17, in <module>
    os.rename(old_name, new_name)     
FileNotFoundError: [Errno 2] No such file or directory: 'notes' -> 'notes.html.pmd'

I know that my problem is somewhat similar to theirs. Yet, it is different in that my code is meant to rename also the files in subdirectories, hence recursive=True parameter.

What am I doing wrong? What is the simplest way to rename files recursively?


Solution

  • You’re renaming the same old_name == "notes" to new_name == "notes.html.pmd" over and over instead of using the paths provided by glob.glob. I’d use pathlib:

    #!/usr/bin/env/python3
    
    from pathlib import Path
    
    old_name = "notes"
    new_name = "notes.html.pmd"
    
    for old_path in Path(".").glob(f"**/{old_name}"):
        old_path.rename(old_path.parent / new_name)