Python recursive file renaming

Question:

I am pretty new to python and I am attempting to create a python script that is able to recursively rename every file in a directory including subdirectories. But every time I run the script I’m getting the error

OSError: [Errno 2] No such file or directory

The directory contains some text files and a folder with some other files.

Does anyone know why this keeps happening?

Code:

import os
path = "example path here"
new_filename= ""
i = 0

filenames = os.listdir(path) # is this line needed?
for dir,subdir,listfilename in os.walk(path):
    for filename in listfilename:
        i += 1
        new_filename = 'filename' + str(i)
        src = os.path.join(path, filename)
        dst = os.path.join(path, new_filename)
        os.rename(src, dst)
Asked By: user3702643

||

Answers:

I’m fairly certain the issue stems from you joining new paths to the “path” variable rather than the current directory returned from walk.

import os
path = "example path here"
new_filename= "" # This isn't C, we don't need to pre-declare a variable.
i = 0

filenames = os.listdir(path) # is this line needed? # not that I can see, no
for dir,subdir,listfilename in os.walk(path):
    for filename in listfilename:
        i += 1
        new_filename = 'filename' + str(i)
        src = os.path.join(dir, filename) # NOTE CHANGE HERE
        dst = os.path.join(dir, new_filename) # AND HERE
        os.rename(src, dst)

You should go read the docs for os.walk, I’m not sure you fully understand what it does?

Also, don’t call a variable dir, it’ll mask the builtin by the same name.

Also also, you don’t need to pre-declare path outside of your loops.

Answered By: LexyStardust
"""
  Rename files in current directory and subdirectories recursively; 
  by default substitute spaces with underscores.
"""

import os
import argparse

def main() -> None:

  cwd = os.getcwd()

  parser = argparse.ArgumentParser()
  parser.add_argument('-d', '--directory', default=cwd)
  parser.add_argument('-t', '--target', default=" ")
  parser.add_argument('-r', '--replacement', default="_")
  args = parser.parse_args()

  walk_dir(os.path.realpath(args.directory), args.target, args.replacement)


def walk_dir(dir: str, t: str, r: str) -> None:
  for dirpath, dirs, files in os.walk(dir):
    rename_files(files, dirpath, t, r)
    for dir in dirs:
      walk_dir(dir, t, r)


def rename_files(files: list, dir: str, t: str, r: str) -> None:
  for file in files:
    filepath_old = os.path.join(dir, file)
    filepath_new = os.path.join(dir, file.replace(t, r))
    os.rename(filepath_old, filepath_new)
    print(f"{filepath_old} -> {filepath_new}")

if __name__ == "__main__":
    main()
Answered By: Matteo Mazzanti
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.