如何在Python中更改文件夹名称?

53

我有多个名字为人名的文件夹,其中名字在前、姓氏在后。我希望更改文件夹名称,以便姓氏在前面,后跟逗号,然后是名字。

例如,在名为Test的文件夹中,我有:

C:/Test/John Smith
C:/Test/Fred Jones
C:/Test/Ben Jack Martin

我想实现这个:

C:/Test/Smith, John
C:/Test/Jones, Fred
C:/Test/Martin, Ben Jack

我尝试使用os.rename做一些事情,但是我似乎无法处理具有不同名称长度的文件夹,并且我不确定如何将逗号插入到姓氏中。

此外,一些文件夹名称已经处于正确的形式,因此在重命名过程中需要跳过这些文件夹。我认为可以通过添加一个if语句来实现这一点,如果文件夹名称包含逗号,则继续进行操作。

否则,姓氏将始终是文件夹名称中的最后一个单词。

感谢您提供的任何帮助。

6个回答

50

您可以相当直接地编写它,使用os.listdiros.path函数:

import os
basedir = 'C:/Test'
for fn in os.listdir(basedir):
  if not os.path.isdir(os.path.join(basedir, fn)):
    continue # Not a directory
  if ',' in fn:
    continue # Already in the correct form
  if ' ' not in fn:
    continue # Invalid format
  firstname,_,surname = fn.rpartition(' ')
  os.rename(os.path.join(basedir, fn),
            os.path.join(basedir, surname + ', ' + firstname))

这意味着在您的系统上不存在C:/Test。 您确定那是您的用户名目录所在的目录吗? - phihag
这意味着c:\Test完全不存在。 - jgritty
我已经在其他文件夹中使用了这段代码,但是在某些文件夹中出现了以下错误:[Error 183] Cannot create a file when that file already exist. 这只是因为有些文件夹已经同时包含了正确的名称和不正确的名称。我想要将这些文件夹合并。如果我在代码中添加另一个if语句,那么如果文件夹已经存在,它们的内容是否可以合并? - user1130955
@user1130955 嗯,你的if应该放在os.rename之前,如果它命中了,你应该跳过这个条目(即continue)。整段代码看起来像这样:if os.path.exists(os.path.join(basedir, surname + ', ' + firstname)): continue - phihag
@phihag 这似乎只是在正确的文件夹名称已经存在的情况下跳过此文件夹,而不是合并这些文件夹,这正是我想要的。 - user1130955
显示剩余3条评论

37
os.rename("Joe Blow", "Blow, Joe")

对我来说似乎运行良好。你哪部分有困难?


当我为每个文件夹单独执行时,这很好,但是我似乎无法使其适用于遍历所有文件夹的循环。问题是我不知道如何为所有文件夹指定名字和姓氏。 - user1130955
phihag 上面的例子可能完美地运行。他使用 rnpartition 来分割字符串。我可能只会使用 split(),但他的例子应该可以工作。 - jgritty
只能用于非空文件夹。 - Jürgen K.
这不是真的...无论文件夹是否为空,这都可以工作。 - jgritty
那么至少可以肯定的是,有时 os.rename() 不起作用,错误消息中包含对空值或缺乏的引用。对于在 macOS 中收到类似 OSError: [Errno 66] Directory not empty: 的错误的人,这可能会起作用 https://dev59.com/Emoy5IYBdhLWcg3wKq4S#62154151。 - uhoh

14

os.rename的替代方案是shutil.move(src, dest)

import shutil
import os
shutil.move("M://source/folder", "M://destination/folder") 
os.rename("M://source/folder", "M://destination/folder")

区别

  1. 如果源路径和目标路径位于不同的文件系统或驱动器,OS模块可能会移动文件失败。但是在这种情况下,shutil.move不会失败。
  2. shutil.move检查源路径和目标路径是否位于同一文件系统上。但是,os.rename不检查,因此有时会失败。

  3. 在检查源路径和目标路径后,如果发现它们不在同一文件系统上,则shutil.move将首先将文件复制到目标位置。然后它将从源文件中删除文件。因此,我们可以说在Python中当源路径和目标路径不在同一驱动器或文件系统上时,shutil.move是一种更智能的移动文件的方法。

  4. shutil.move适用于高级函数,而os.rename适用于低级函数。

我还建议使用pathlib来操作路径:

from shutil import move
from pathlib import Path


base_path = Path("C:/Test")

for folder in base_path.iterdir():
    if not folder.is_dir() or folder.name.startswith("."):
        continue

    name = folder.name
    new_name = ", ".join(name.split(" "))
    new_folder = folder.parent / new_name

    move(folder, new_folder)



解释只是额外的奖励。为您提供比较和选择。 - James Walker

7
您可以只使用一个命令,并带上完整路径。
import os
os.rename("/path/old_folder_name", "/path/new_folder_name")

3

我喜欢phihag的建议, 使用rpartition()方法,我认为以下内容基本等效:

>>> 'first second third fourth'.rpartition(' ')
('first second third', ' ', 'fourth')
>>> 'first second third fourth'.rsplit(None, 1)
['first second third', 'fourth']

我更喜欢使用rsplit(),因为我不想关心分隔符,但我也可以看到它有点啰嗦。 设置
>>> base = 'C:\\Test'
>>> os.makedirs(os.path.join(base, 'John Smith'))
>>> os.makedirs(os.path.join(base, 'Fred Jones'))
>>> os.makedirs(os.path.join(base, 'Ben Jack Martin'))
>>> os.listdir(base)
['Ben Jack Martin', 'Fred Jones', 'John Smith']

解决方案

>>> for old_name in os.listdir(base):
    # [::-1] is slice notation for "reverse"
    new_name = ', '.join(old_name.rsplit(None, 1)[::-1])
    os.rename(os.path.join(base, old_name),
          os.path.join(base, new_name))


>>> os.listdir(base)
['Jones, Fred', 'Martin, Ben Jack', 'Smith, John']

1
  1. os.rename有时无法正常工作。

  2. 为确保它重命名文件夹,请使用os.chdir。

  3. 在下面的示例中,我们正在更改主文件夹中找到的子目录的名称。

    main_folder=r"C:\Users\clipped_features"
    path_file=os.listdir(main_folder)
    
    for i in range(len(path_file)):
      #在重命名之前应用os.chdir
      os.chdir(main_folder)
      os.rename(os.path.join(main_folder,path_file[i],"new_name"))
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接