( Python ) 递归去掉目录结构中的大写字母?

3 投票
2 回答
5261 浏览
提问于 2025-04-16 00:10

大写字母 - 它们有什么用呢?只会让你手腕受伤。

我想尽量去掉我文件夹结构中的大写字母。我要怎么写一个Python脚本来做到这一点呢?

这个脚本应该能递归地检查指定的文件夹,找到那些名字里有大写字母的文件和文件夹,然后把它们的名字改成小写。

2 个回答

2

试试下面这个脚本:

#!/usr/bin/python

'''
renames files or folders, changing all uppercase characters to lowercase.
directories will be parsed recursively.

usage: ./changecase.py file|directory
'''

import sys, os

def rename_recursive(srcpath):
    srcpath = os.path.normpath(srcpath)
    if os.path.isdir(srcpath):
        # lower the case of this directory
        newpath = name_to_lowercase(srcpath)
        # recurse to the contents
        for entry in os.listdir(newpath): #FIXME newpath
            nextpath = os.path.join(newpath, entry)
            rename_recursive(nextpath)
    elif os.path.isfile(srcpath): # base case
        name_to_lowercase(srcpath)
    else: # error
        print "bad arg: " + srcpath
        sys.exit()

def name_to_lowercase(srcpath):
    srcdir, srcname = os.path.split(srcpath)
    newname = srcname.lower()
    if newname == srcname:
        return srcpath
    newpath = os.path.join(srcdir, newname)
    print "rename " + srcpath + " to " + newpath
    os.rename(srcpath, newpath)
    return newpath

arg = sys.argv[1]
arg = os.path.expanduser(arg)
rename_recursive(arg)
16

os.walk 是一个很棒的工具,可以用来处理文件系统中的递归操作。

import os

def lowercase_rename( dir ):
    # renames all subforders of dir, not including dir itself
    def rename_all( root, items):
        for name in items:
            try:
                os.rename( os.path.join(root, name), 
                                    os.path.join(root, name.lower()))
            except OSError:
                pass # can't rename it, so what

    # starts from the bottom so paths further up remain valid after renaming
    for root, dirs, files in os.walk( dir, topdown=False ):
        rename_all( root, dirs )
        rename_all( root, files)

向上遍历目录树的好处在于,当你有一个像 '/A/B' 这样的目录结构时,在递归过程中你也会得到路径 '/A'。如果你从最上面开始,比如先把 /A 改成 /a,那么 /A/B 的路径就会失效了。相反,如果你从最下面开始,先把 /A/B 改成 /A/b,这样就不会影响到其他的路径。

其实你也可以用 os.walk 从上到下进行操作,不过那样会稍微复杂一些。

撰写回答