pythonloopsdirectoryrename

Shortening nested folder names


We are utilizing an online file repository (similar to SharePoint but not Microsoft). The problem is it allows the creating of long paths. We are downloading the nested folders as a zip file, and then extracting them locally on the computer, but when we try to upload the unzipped path to SharePoint, it hits the path length limit. The nest is quite long with about 8 to 10 sub folders.

To fix this, I am trying to write a script that will shorten each of the folders to its first 8 characters. I tried in PowerShell but it hit the same path length limit and failed to run. I am attempting this in Python, and I have a loop to walk through the folders, but as soon as it renames the first folder that is longer than 8 characters, it quits the loop and doesn't carry on renaming the rest.

I'm hoping the issue might be obvious to someone else.

Here is the code:

def shorten_folder_names(root_folder, max_length):
    # Create a text file to store the old and new folder names
    with open("folder_names.csv", "w") as file:
        # Walk through all folders and subfolders
        for dirpath, dirnames, filenames in os.walk(root_folder):
            for dirname in dirnames:
                old_name = os.path.join(dirpath, dirname)
                # Skip folders that are already shorter than the specified length
                if len(dirname) <= max_length:
                    continue
                new_name = os.path.join(dirpath, dirname[:max_length])
                # Rename the folder to the new name (shortened to the specified length)
                os.rename(old_name, new_name)
                # Write the old and new folder names to the text file
                file.write(f"{old_name} -> {new_name}\n")


Solution

  • As you already mentioned, your issues is currently with your loop and ensuring that you stay within that for loop for the entirety of the directory.

    I am rather positive that your current issue stems from the working dirnames value changing while you are still working with it and causing the loop to break. To fix this you can try the following code:

    def shorten_folder_names(root_folder, max_length):
        with open("folder_names.csv", "w") as file:
            for dirpath, dirnames, filenames in os.walk(root_folder):
                for i in range(len(dirnames)):
                    dirname = dirnames[i]
                    old_name = os.path.join(dirpath, dirname)
    
                    if len(dirname) <= max_length:
                        continue
    
                    new_name = os.path.join(dirpath, dirname[:max_length])
    
                    os.rename(old_name, new_name)
    
                    dirnames[i] = dirname[:max_length]
    
                    file.write(f"{old_name} -> {new_name}\n")
    

    In this code we are using a for i loop to go across the amount of directory names. Within each iteration of the loop we are grabbing and setting the name of the current directory we are looking at instead of using that current directory name as our starting value and then changing it within the loop.

    Do note that there is no validation checking here to ensure that two file names are not the same (as that will cause errors for you) so you will need to look into doing that!

    Hope this helps, good luck!