Search code examples
pythonoperating-systemshutil

os.makedirs is creating a new folder with file name


I'm trying to copy all folders and files from one path to another if a file doesn't contain a substring called "obsolete". Here is my code:

import os
import shutil

rootdir = "C:/Old"     
new_rootdir = "C:/New/"

for root, dirs, files in os.walk(rootdir):
    for filename in files:
        if not "obsolete" in filename:
            source = root + "\\" + filename
            extra_paths = source.split("\\")[1:]    # strings to be merged to the new destination
            destination = new_rootdir + "/".join(extra_paths)
        
            if not os.path.exists(destination):
                os.makedirs(destination)  # Create the destination directory if it doesn't exist
        
            if os.path.isdir(source):
                for root, dirs, files in os.walk(source):
                    for directory in dirs:
                        source_path = os.path.join(root, directory)
                        destination_path = os.path.join(destination, os.path.relpath(source_path, source))
                        if not os.path.exists(destination_path):
                            os.makedirs(destination_path)
                    for file in files:
                        source_path = os.path.join(root, file)
                        destination_path = os.path.join(destination, os.path.relpath(source_path, source))
                        shutil.copy2(source_path, destination_path)
            else:
                shutil.copy2(source, destination) 

The script works, but it is creating a new folder for every file with its name on it. For example, for the old path C:/Old/Documents/example.txt it is creating a new path like C:/New/Documents/example.txt/example.txt and it should be C:/New/Documents/example.txt

How can I fix this so the script does not create a folder with the file name?


Solution

  • extra_paths includes the filename. When you concatenate this into destination, you're creating a directory with the name of the destination file. And then later you append the filename to this.

    Use this instead:

                extra_paths = root.split("\\")[1:]    # strings to be merged to the new destination