I made an application in Python (link for source code at the bottom) which renames files (in a directory) by sorting them (based on their extension) into one of these: Image, Video, Text, GIF, Audio and Unknown Extension.
Basically, it loops through a directory, gets all the files in it, sorts them, for each file in the sorted list it assigns a value of its index in list and then renames the file. But, for some reason, it gives the same number twice or misses some in between.
So, I would like to rename them in chronological order, without changing the order in which they appear. For example, the third file before the process should be the same as the third file after the process and so on. like this:
I don’t know how to put my thoughts into Python’s code. But I think you can do it like this:
- Get all the files in a folder (Chronologically).
- If they contain a specific word (like Image or video), add them to the list named after the word it contains.
- Get the length(or count) of the list.
- In a for loop, split the file name by
' '
(Space). Check if the RHS of the name corresponds to the current value of loop, if it doesn’t rename it with the same name but this new value.
Minimal code to copy this error:
import os choice = "Subdirectories included" values = dict ({ "unknownCount" : 0, "textCount" : 0, "imageCount" : 0, "gifCount" : 0, "audioCount" : 0, "videoCount" : 0, }) os.chdir(location) if choice == "Subdirectories included": for root, dirs, files in os.walk(location): for i in sorted(files): fileName = os.path.join(root,i) if fileName.__contains__('.'): ext = fileName.split('.')[1] toR = Give(ext) + "." + ext toRename = root + toR try: os.rename(fileName, toRename) except: error = OSError print(error) def Give(ext): addUnknown = True if ext == "txt": toname = "Text " + str(values["textCount"]) values["textCount"] += 1 addUnknown = False elif ext == "jpg": toname = "Image " + str(values["imageCount"]) values["imageCount"] += 1 addUnknown = False elif ext == "jpeg": toname = "Image " + str(values["imageCount"]) values["imageCount"] += 1 addUnknown = False elif ext == "png": toname = "Image " + str(values["imageCount"]) values["imageCount"] += 1 addUnknown = False elif ext == "gif": toname = "GIF " + str( values["gifCount"]) values["gifCount"] += 1 addUnknown = False elif ext == "mp3": toname = "Audio " + str(values["audioCount"]) values["audioCount"] += 1 addUnknown = False elif ext == "ogg": toname = "Audio " + str(values["audioCount"]) values["audioCount"] += 1 addUnknown = False elif ext == "wav": toname = "Audio " + str(values["audioCount"]) values["audioCount"] += 1 addUnknown = False elif ext == "mkv": toname = "Video " + str(values["videoCount"]) values["videoCount"] += 1 addUnknown = False elif ext == "avi": toname = "Video " + str(values["videoCount"]) values["videoCount"] += 1 addUnknown = False elif ext == "mp4": toname = "Video " + str(values["videoCount"]) values["videoCount"] += 1 addUnknown = False if addUnknown == True: toname = r"Unknown Extension " + str(values["unknownCount"]) values["unknownCount"] += 1 return toname
Advertisement
Answer
Assumed (from the image in the question) that there is a unique format of basename per file extension: format .jpg
-> name format Image D
where D
is a digit(s). Those which do not satisfy the format are treated (and recorded) as exceptions and no actions is performed on them. For more complex situations a regex approach is suggested.
Idea: group by file extensions, sort each group, set new name, rename
Note
- as first run maybe comment the line with
os.rename
- it has been tested only in current directory
Here a possible approach:
import os # path of the dir path_dir = '.' # get all file extensions in the directory exts = [f.split('.')[-1] for f in os.listdir(path_dir)] # get all file names in the directory files = os.listdir(path_dir) # group by file extension & format groupby_ext = {} for f in files: for ext in exts: if f.endswith(ext): # check file format condition if ' ' in f: groupby_ext.setdefault(ext, set()).add(f[:-len(ext)-1]) else: # those who do NOT satisfy the name format conditions groupby_ext.setdefault('exceptions', []).append(f) for ext, files in groupby_ext.items(): if ext == 'exceptions': continue # sort by name and rename for i, bname in enumerate(sorted(files, key=lambda s: int(s.split()[-1]))): # new name new_bname = f'{bname.split()[0]} {i}.{ext}' # change name print(bname, '-->', new_bname) os.rename(f'{bname}.{ext}', new_bname) # maybe comment this line before running the program # no actions on them print(groupby_ext['exceptions'])