1

Python novice, my simple script gets a given directory and renames all files sequentially, however it is deleting the files but the print is showing the files names getting renamed, not sure where its going wrong here.

Also, in what order does it retrieve these files?

import os

path = os.path.abspath("D:\Desktop\gp")
i = 0
for file_name in os.listdir(path):

    try:
        print (file_name + " - " + str(i))
        os.rename(os.path.join(path,file_name), str(i))
    except WindowsError:
        os.remove(str(i))
        os.rename(os.path.join(path,file_name), str(i))

    i += 1

print(str(i) + " files.")

Edit

Below is the solution with working code, retrieves all files in a dir by creation date and assigns them a iterated number while retaining file extension.

import os

def sorted_dir(folder):
    def getctime(name):
        path = os.path.join(folder, name)
        return os.path.getctime(path)
    return sorted(os.listdir(path), key=getctime)

path = os.path.abspath("D:\Path\Here")
i = 0
for file_name in sorted_dir(path):
    _, ext = os.path.splitext(file_name)
    print (file_name + " - " + str(i)+ext)    
    os.rename(os.path.join(path,file_name), os.path.join(path, str(i) + ext))
i += 1

print(str(i-1) + " files.")
Liam Morgan
  • 136
  • 2
  • 13
  • 1
    Your indenting is broken. – Stephen Rauch Mar 22 '18 at 00:49
  • fixed, was just a copy+paste issue for stack overflow, problem persists. – Liam Morgan Mar 22 '18 at 00:52
  • I did not think the problem would go away, it is just hard to read the code. – Stephen Rauch Mar 22 '18 at 00:53
  • (1) Are you sure it's deleting the files, not just moving them from `D:\Desktop\gp` to wherever your current working directory is? – abarnert Mar 22 '18 at 00:57
  • (2) Are you getting inside that `except WindowsError:` and calling `os.remove`? I notice that you don't print anything out when that happens. – abarnert Mar 22 '18 at 00:57
  • Ah, they are being moved to the current working directory with no file attachment. How would i fix this? I have moved them back to the standard directory. (And retain their file extension next time?) – Liam Morgan Mar 22 '18 at 01:00
  • Also, you're getting lucky here, but you shouldn't use Windows pathnames with backslashes without raw strings or escaping the backslashes. See https://stackoverflow.com/questions/2953834/windows-path-in-python – abarnert Mar 22 '18 at 01:00
  • To fix it, just use `os.path.join`, the same way you did with `file_name`. See my answer. – abarnert Mar 22 '18 at 01:02
  • As for the extension… did you want the files to be named like `1.jpg`, `2.txt`, `3.mp4`, etc. instead of just `1`, `2`, `3`, etc.? – abarnert Mar 22 '18 at 01:03
  • It's a little simpler, and a little faster (sometimes a _lot_ faster on Windows) to use `scandir` instead of `listdir`. Then, instead of having to do `os.path.getctime(os.path.join(path, file))` you can just do `entry.stat().st_ctime`. – abarnert Mar 22 '18 at 03:26

1 Answers1

5

The problem is that you're using an absolute path for the source, but a relative path for the destination. So the files aren't getting deleted, they're just getting moved into the current working directory.

To fix it so they get renamed into the same directory they were already in, you can do the same thing on the destination you do on the source:

os.rename(os.path.join(path,file_name), os.path.join(path, str(i)))

From a comment, it sounds like you may want to preserve the extensions on these files. To do that:

_, ext = os.path.splitext(file_name)
os.rename(os.path.join(path,file_name), os.path.join(path, str(i) + ext))
abarnert
  • 354,177
  • 51
  • 601
  • 671
  • Great answer, can i ask what _, is? – Liam Morgan Mar 22 '18 at 01:07
  • 2
    `_` is just a common way to assign something to something you do not care about. – Stephen Rauch Mar 22 '18 at 01:10
  • What would i normally use this for? – Liam Morgan Mar 22 '18 at 01:11
  • 2
    To ignore a return value. – Stephen Rauch Mar 22 '18 at 01:11
  • @LiamMorgan: In this case, `splitext` returns two values, the name and the extension.. If I wrote `name, ext = …` instead, it would do exactly the same thing to Python. But to a human reader, `_, ext = …` means that I care about `ext` but don't care about the other value. – abarnert Mar 22 '18 at 01:17
  • I get it, as splittext returns 2 values no?, Also a follow up question - Is there any way to retrieve the files in the path by date created, so that i can name them in this order? Edit: woops, just read your comment again about splittext. – Liam Morgan Mar 22 '18 at 01:29
  • @LiamMorgan Instead of trying to retrieve them in order, use os.scandir to fetch directory entries instead of just file names, then sort those by whatever you want. – abarnert Mar 22 '18 at 02:14
  • Thanks for the help, gonna edit original question to reflect final working code. – Liam Morgan Mar 22 '18 at 02:17
  • Thanks! It wors! Is better to indicate a relative path like -> my_path/folder_1. Because with -> /home/my_user/my_path/folder_1 it shows problems. – ambigus9 Nov 18 '21 at 16:07