递归重命名文件和文件夹

3 投票
2 回答
2868 浏览
提问于 2025-04-18 10:29

背景

目前我正在研究大型数字档案库。根据法律,这些档案需要保存20到70年左右。我的研究主要是关于如何通过企业搜索解决方案来检索这些档案中的文件。在我能对这些档案进行任何操作之前,首先需要将它们复制到本地存储。大多数档案是通过USB驱动器和闪存棒传送给我的。这些档案的大小在4GB到250GB之间。同时,我也在学习用Python编写脚本,以便能够实现搜索解决方案。

问题

复制文件和文件夹时遇到了一些麻烦,因为文件和文件夹的层级结构很深。很多文件或文件夹的名字都比较长(有时候超过了Windows系统能处理的255个字符)。

解决方案

我打算写一个Python脚本,递归地去掉文件和文件夹名称中的空格,把它们缩短到255个字符以内。同时,为了保留旧的名称,新的名称会采用驼峰命名法(camelCase)。

问题

我已经写了一个脚本,可以去掉空格并将文件和文件夹名称转换为驼峰命名法。但这个脚本只对选定的目录有效,并不是递归的。我尝试使用os.walk函数,但似乎无法通过os.walk实际更改名称。使用os.listdir可以更改名称,但我不太明白如何做到递归处理。那么,如何用Python递归地重命名文件和文件夹呢?

代码

import os

current_path  = os.getcwd() # testing only
print current_path
path = "k:/test3/"
os.chdir(path)
current_path  = os.getcwd()
print current_path # testing only
new_filename= ""
#filenames = os.walk(path, topdown=False)

# all print statusses should be rewritten to lines in log files.

filenames =os.listdir(path)
print filenames
for filename in filenames:
    print "\nOldname: \n" +filename
    new_filename = filename.lower().strip() 
    #make sure all filenames are in lowercase and cut whitespace on both ends.
    if " " in filename: #test for spaces in file or foldername
        fn_parts= [w.capitalize() for w in filename.split()]
        print "The parts are: "
        print  fn_parts
        new_filename="" #empty new_filename after last iteration
        new_filename=new_filename.join(fn_parts)
        print "New filename: \n"+new_filename + "\n"
        os.rename(os.path.join(path, filename), os.path.join(path, new_filename))
    else:
        new_filename=new_filename.title()
        print "New filename: \n"+new_filename + "\n"
        os.rename(os.path.join(path, filename), os.path.join(path, new_filename))

2 个回答

0

我在Linux上使用Python的经验比较多,但也许你可以通过一个叫做“glob”的方法来遍历那个驱动器里的文件。

https://docs.python.org/2/library/glob.html

然后可以用“shutil”这个工具来移动或复制文件到新的位置?

https://docs.python.org/2/library/shutil.html?

这两个工具都非常简单易用,不过如果你在使用它们时遇到具体问题,Stack Overflow上已经有很多相关的答案可以参考。

祝你好运!

1

我不太确定,但使用 os.walk 的代码修改可能会对你有帮助,希望如此。

import os
current_path  = os.getcwd() # testing only
print current_path
path = "k:/test3/"
os.chdir(path)
current_path  = os.getcwd()
print current_path # testing only
new_filename= ""
#filenames = os.walk(path, topdown=False)

# all print statusses should be rewritten to lines in log files.

filenames =os.listdir(path)
print filenames
for dir,subdir,listfilename in os.walk(path):

    for filename in listfilename:
        print "\nOldname: \n" +filename 
        new_filename = filename.lower().strip() 
        #make sure all filenames are in lowercase and cut whitespace on both ends.
        if " " in filename: #test for spaces in file or foldername
            fn_parts= [w.capitalize() for w in filename.split()]
            print "The parts are: "
            print  fn_parts
            new_filename="" #empty new_filename after last iteration
            new_filename=new_filename.join(fn_parts)
            print "New filename: \n"+new_filename + "\n"
            os.rename(os.path.join(dir, filename), os.path.join(path, new_filename))
        else:
            new_filename=new_filename.title()
            print "New filename: \n"+new_filename + "\n"
            os.rename(os.path.join(path, filename), os.path.join(path, new_filename))

撰写回答