Python:如何在ALL文件,文件夹和子文件夹的名称中用下划线替换空格?

时间:2016-12-16 02:45:39

标签: python batch-rename

如何替换给定父文件夹中文件夹,子文件夹和文件名称中的空格?

我最初尝试更换到8级,如下所示。我相信有更好的方法。我的代码看起来很难看。 更好的解决方案非常受欢迎。

#!/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('*')

3 个答案:

答案 0 :(得分:7)

您可以使用os.walk来允许您动态更改已迭代文件夹的名称:

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以自上而下的顺序从parent开始迭代目录树。对于每个文件夹,它返回元组(current path, list of files, list of folders)。给定文件夹列表可以变异,os.walk将在迭代的以下步骤中使用变异内容。

运行前的文件夹:

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

后:

.
├── new_doc
└── sub_folder
    ├── another_folder
    ├── norename
    └── space_here

答案 1 :(得分:1)

您需要一个递归解决方案。重命名当前目录中的所有文件;然后对于每个子目录(如果有的话),下降到该子目录X(使用os.chdir(X)),再次调用相同的函数,然后返回到父目录(使用os.chdir(".."))。

答案 2 :(得分:0)

按照@niemmi的确切想法,我最终得到了这个:

警告:永远不要从HOME目录或某个重要目录运行此脚本,它将重命名所有文件,包括HIDDEN文件。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Date: Dec 15, 2016


def replace_space_by_underscore(parent):
    """Replace whitespace by underscore in all files and folders.

    replaces    , - [ ] () __   ==>  underscore

    """
    import os
    for path, folders, files in os.walk(parent):
        # rename the files
        for f in files:
            old = os.path.join(path, f)
            bad_chars = [r' ', r',', r'-', r'&', r'[', r']', r'(', r')', r'__']
            for bad_char in bad_chars:
                if bad_char in f:
                    new = old.replace(bad_char, '_')
                    print(old, "==>", new)
                    os.rename(old, new)

        # rename the folders
        for i in range(len(folders)):
            new_name = folders[i].replace(' ', '_')
            bad_chars = [r' ', r',', r'-', r'&',
                         r'[', r']', r'(', r')', r'__']
            for bad_char in bad_chars:
                if bad_char in new_name:
                    new_name = new_name.replace(bad_char, '_')
                    print(folders[i], "==> ", new_name)
            old = os.path.join(path, folders[i])
            new = os.path.join(path, new_name)
            os.rename(old, new)
            folders[i] = new_name


if __name__ == "__main__":
    replace_space_by_underscore('.')