Python Forum
mass rename files in folders - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: mass rename files in folders (/thread-7216.html)



mass rename files in folders - kerzol81 - Dec-28-2017

hi all,

I got this code:

import os

def renamer(folder):
    dirname = folder
    files = os.listdir(folder)
    os.chdir(folder)
    for i in files:
        os.rename(i, dirname + '_' + i)


renamer('abc')
it works if I give an example folder to the function. But it doesnt work in a for cycle like this:

for i in os.listdir('.'):
    renamer(i)
i have tons of folders that contain video files like this: file-1.mp4, file-2.mp4, file-3.mp4, and I'd like the files renamed a way that the new filename would contain the parent directory's name included: abc_file-1.mp4

Could you please help me to fix this code?


RE: mass rename files in folders - wavic - Dec-28-2017

Which Python version you are using. os.scandir is much faster than os.listdir.

If 'i' happens to be a file you can't use os.listdir on it.

See os.walk


RE: mass rename files in folders - kerzol81 - Dec-28-2017

I use python 3.6, i modified the script, but it still doesnt work

import os

def renamer(*folder):
    dirname = folder
    files = os.listdir(folder)
    os.chdir(folder)
    for i in files:
        os.rename(i, dirname + '_' + i)



for root, dirs, files in os.walk('.'):
    dirs[:] = [d for d in dirs if not d[0] == '.']

    renamer(dirs)



RE: mass rename files in folders - wavic - Dec-29-2017

import os
from sys import argv

path = argv[1] # take the directory from the command line.
for root, dirs, files in os.walk(path):
    for file in files:
        dir = os.path.split(root)[-1]
        os.rename(file, f"{dir}-{file}")
os.walk starts from the 'path' and for each directory from the three returns a tuple:
{the_current_directory,
 a_list_of_all_directories_in_the_current_directory,
 a_list_of_all_files_in_the_current_directory)
So, you just pass the path to the os.walk and for each iteration, you change the names of the 'files' from the tuple (root, dirs, files). 'files' is a list of all files in 'root', which is the current directory during the scan.


RE: mass rename files in folders - kerzol81 - Dec-29-2017

Your script makes hidden files from regular files:-) in current folder, and that
os.rename(file, f"{dir}-{file}")
is buggy, by the way it was a good idea to take the input folder as a command line argument.

mine is buggy still:

for root, folders, files in os.walk('test'):

    for file in files:
        folder = os.path.split(root)[1]

        src = file
        dst = folder + '_' + file

        os.rename(src, dst)
it complains:
FileNotFoundError: [Errno 2] No such file or directory: 'file-1.mp4' -> 'def_file-1.mp4'

It's crazy, if I replace os.rename(scr, dst) with print(src, dst), it finds the files:-)


RE: mass rename files in folders - wavic - Dec-29-2017

That is because the command line argument is '.' and as you may know the dot in the beginning of a file/dir name in *nix systems makes them hidden.
Change it like this:

import os
from sys import argv
 
path = os.path.abspath(argv[1])
for root, dirs, files in os.walk(path):
    for file in files:
        dir = os.path.split(root)[-1]
        os.rename(file, f"{dir}-{file}")


This change should make it works:
for root, folders, files in os.walk('test'):
 
    for file in files:
        folder = os.path.split(root)[1]
        file_name = f"{folder}_{file}"
        src = os.path.join(root, file_name)
        os.rename(src, dst)