Dude
Dude

Reputation: 145

Renaming files in a folder with pathlib and for loops

I've written the following renaming tool in Python. It was unintentionally moving all my files to a single directory until I added the os.chdir in my for loop, which then made it work better and keep each renamed file inside its correct folder. But I don't really understand the logic behind why this script, without the os.chdir, was moving all my files to a single directory, can somebody help me understand? Thank you.

import pathlib
from pathlib import Path
import os

folderDir = Path(input("Please enter the parent directory: \n"))

folderList = [folder for folder in folderDir.iterdir() if folder.is_dir()]

for f in folderList:
    
    fileList = [e for e in f.iterdir() if e.is_file()]

    os.chdir(f)

    count = 1
    for i in fileList:
        folderName = os.path.basename(os.path.dirname(i))
        i.rename(folderName + "_" + str(count).zfill(3) + pathlib.Path(i).suffix)
        count += 1

Upvotes: 0

Views: 1068

Answers (2)

hemmond
hemmond

Reputation: 1

Pathlib documentation states:

The target path may be absolute or relative. Relative paths are interpreted relative to the current working directory, not the directory of the Path object.

You are using value from os.path.basename() as first argument of i.rename() - that gives only folder name, so that basically creates relative path.

Your code depends on user giving valid absolute path. If user does so, iterdir() returns absolute paths, otherwise you will get relative paths.

So I'd recommend to sanitize your input so it always give absolute path:

folderDir = Path(input("Please enter the parent directory: \n")).absolute()

And then if you want to drop the os.chdir (and whole os module while you're at it) you can do this:

for i in fileList:
    folderName = i.parent.name
    i.rename(i.parent.parent, folderName + "_" + str(count).zfill(3) + pathlib.Path(i).suffix)
    count += 1

folderName shoud still contain the folder inside which the files are stored and the i.parent.parent in i.rename() is to get absolute path of folder in which you operate. Otherwise I just replaced os.path methods with Pathlib methods usong table in Pathlib's documentation.

Upvotes: 0

GhandiFloss
GhandiFloss

Reputation: 384

I would assume this is because it was renaming the files to your current working directory (ie wherever you saved the script) rather than the actual directory where the files were stored.

file = your/file/name.txt
os.path.dirname(file) # This gives 'your/file'
os.path.basename(your/file) # This gives 'file'

The script was therefor creating a folder called 'file' in the example above in your cwd. By adding in the chdir(f), it creates in this directory instead as this already exists it modifies the existing file. Which is what you want.

I may be wrong but that it is my understanding. I hope this makes sense.

Upvotes: 1

Related Questions