Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: How to replace whitespaces by underscore in the name of ALL files, folders and subfolders?

How can we replace the whitespaces in the names of folders, subfolders and files in a given parent folder?

My initial attempt to replace up to level 8 is given below. I am sure there are better ways. My code looks ugly. Better solutions are more than welcome.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#


def replace_space_by_underscore(path):
    """Replace whitespace in filenames by underscore."""
    import glob
    import os
    for infile in glob.glob(path):
        new = infile.replace(" ", "_")
        try:
            new = new.replace(",", "_")
        except:
            pass
        try:
            new = new.replace("&", "_and_")
        except:
            pass
        try:
            new = new.replace("-", "_")
        except:
            pass
        if infile != new:
            print(infile, "==> ", new)
        os.rename(infile, new)

if __name__ == "__main__":
    try:
        replace_space_by_underscore('*/*/*/*/*/*/*/*')
    except:
        pass
    try:
        replace_space_by_underscore('*/*/*/*/*/*/*')
    except:
        pass
    try:
        replace_space_by_underscore('*/*/*/*/*/*')
    except:
        pass
    try:
        replace_space_by_underscore('*/*/*/*/*')
    except:
        pass
    try:
        replace_space_by_underscore('*/*/*/*')
    except:
        pass
    try:
        replace_space_by_underscore('*/*/*')
    except:
        pass
    try:
        replace_space_by_underscore('*/*')
    except:
        replace_space_by_underscore('*')
like image 468
BhishanPoudel Avatar asked Dec 19 '22 11:12

BhishanPoudel


1 Answers

You could use os.walk that allows you to change the names of the iterated folders on the fly:

import os

def replace(parent):
    for path, folders, files in os.walk(parent):
        for f in files:
            os.rename(os.path.join(path, f), os.path.join(path, f.replace(' ', '_')))
        for i in range(len(folders)):
            new_name = folders[i].replace(' ', '_')
            os.rename(os.path.join(path, folders[i]), os.path.join(path, new_name))
            folders[i] = new_name

os.walk iterates directory tree starting from parent in top-down order. For every folder it returns tuple (current path, list of files, list of folders). Given folder list can be mutated and os.walk will use the mutated contents in the following steps of the iteration.

Folder before run:

.
├── new doc
└── sub folder
    ├── another folder
    ├── norename
    └── space here

After:

.
├── new_doc
└── sub_folder
    ├── another_folder
    ├── norename
    └── space_here
like image 160
niemmi Avatar answered Apr 29 '23 00:04

niemmi