【问题标题】:Change image names using os.walk to include parent directory names使用 os.walk 更改图像名称以包含父目录名称
【发布时间】:2018-01-16 00:15:35
【问题描述】:

我想根据图像所在文件夹的部分名称重命名图像并遍历图像。我正在使用 os.walk,我能够重命名文件夹中的所有图像,但无法弄清楚如何使用文件夹名称中第一个连字符左侧的字母作为图像名称的一部分。

文件夹名称:ABCDEF - THIS IS - MY FOLDER - NAME

文件夹中的当前图像名称:

dsc_001.jpg 
dsc_234.jpg
dsc_123.jpg

想改成这样显示:

ABCDEF_1.jpg
ABCDEF_2.jpg
ABCDEF_3.jpg

我所拥有的是这个,但我不确定为什么我无法用连字符分割文件名:

import os
from os.path import join

path = r'C:\folderPath'
i = 1

for root, dirs, files in os.walk(path):
    for image in files:
        prefix = files.split(' - ')[0]
        os.rename(os.path.join(path, image), os.path.join(path, prefix + '_' 
        + str(i)+'.jpg'))
        i = i+1

【问题讨论】:

  • 你的意思是image.split 不是files.split,不是吗?
  • 我认为我需要使用 files.split,因为我想在图像名称中使用文件名的第一部分
  • files 是文件名列表。 image 是当前文件的名称。

标签: python os.walk


【解决方案1】:

好的,我重新阅读了您的问题,我想我知道出了什么问题。

1.) os.walk() 迭代器是递归的,即如果您使用os.walk(r'C:\'),它将遍历所有文件夹并找到所有 C下的文件驾驶。现在我不确定您的 C:\folderPath 中是否有任何子文件夹。如果是这样,并且任何文件夹/文件格式都不是 C:\folderPath 的约定,那么您的代码将会很糟糕。

2.) 当您遍历 files 时,您是在 split() 输入错误的对象。您的问题表明您要拆分文件夹名称,但您的代码正在拆分 files 可迭代,这是当前迭代目录下所有文件的列表。这并不能实现你想要的。根据您的 ABCDEF 文件夹是 C:\folderPath 还是其中的子文件夹,您需要进行不同的编码。

3.) 你已经从os.path 导入了join,但你最终还是调用了全名os.path.join(),这是多余的。要么只使用import os 并调用os.path.join(),要么只使用您当前的导入,只需join()

说了这么多,以下是我的编辑:

答案 1:

如果您的 ABCDEF 是分配的文件夹

import os
from os.path import join

path = r'C:\ABCDEF - THIS - IS - MY - FOLDER - NAME'

for root, dirs, files in os.walk(path):
    folder = root.split("\\")[-1] # This gets you the current folder's name
    for i, image in enumerate(files):
        new_image = "{0}_{1}.jpg".format(folder.split(' - ')[0], i + 1)
        os.rename(join(path, image), join(path, new_image))
    break # if you have sub folders that follow the SAME structure, then remove this break.  Otherwise, keep it here so your code stop after all the files are updated in your parent folder.

答案 2:

假设您的 ABCDEF 都是指定目录下的子文件夹,并且所有都遵循相同的命名约定。

导入操作系统 from os.path 导入加入

path = r'C:\parentFolder' # The folder that has all the sub folders that are named ABCDEF...

for i, (root, dirs, files) in enumerate(os.walk(path)):
    if i == 0: continue # skip the parentFolder as it doesn't follow the same naming convention
    folder = root.split("\\")[-1] # This gets you the current folder's name
    for i, image in enumerate(files):
        new_image = "{0}_{1}.jpg".format(folder.split(' - ')[0], i + 1)
        os.rename(join(path, image), join(path, new_image))

注意:

如果您的方案不属于上述任何一种,请说明您的文件夹结构是什么(包括所有子文件夹和子文件的示例)。请记住,一致性是确定代码应该如何工作的关键。如果不一致,最好的办法是分别在 每个 目标文件夹上使用答案 1。

变化:

1.) 您可以在不执行i += 1 的情况下获得增量索引。 enumerate() 是一个很棒的可迭代工具,它还可以为您提供迭代次数。

2.) 您的split() 应该在文件夹名称上操作,而不是files(可迭代)。在您的情况下,image 是实际文件名,files 是当前迭代目录中的文件列表。

3.) 使用str.format() function 使您的新文件格式更易于阅读。

4.) 您会注意到使用了split("\\") 而不是split(r"\"),那就是because a single backslash cannot be a raw string.

现在应该可以了。我最终做了比预期更多的研究,例如how to handle the os.walk() properly in both scenarios. 供将来参考,谷歌搜索有很长的路要走。我希望这最终能回答你的问题。请记住,进行自己的研究并清楚地展示您的问题将使您获得更有效的答案。

奖励:如果你有 python 3.6+,你甚至可以使用f strings 作为你的新文件名,最终看起来真的很酷:

new_image = f"{image.split(' - ')[0]}_{i+1}.jpg"

【讨论】:

  • 感谢您的帮助!我确实试了一下,但仍然出现找不到文件的错误:Traceback(最近一次调用最后一次):文件“C:/Users/mypla/Desktop/testloop.py”,第 11 行,在 os.rename (os.path.join(path, image), os.path.join(path, new_image)) FileNotFoundError: [WinError 2] 系统找不到指定的文件:'C:\\Users\\mypla\\Desktop\ \1_Japanese\\dsc_342.jpg' -> 'C:\\Users\\mypla\\Desktop\\1_Japanese\\dsc_342_2.jpg_2.jpg'
  • 哦,天哪,我刚刚第二次阅读您的帖子,我认为代码从根本上做了不同的事情。我以为文件在根文件夹path 下,但似乎它们实际上在子目录中?也许共享一个示例文件夹/文件结构?
  • 哇,刚刚做了一个巨大的编辑。我希望涵盖它 - 如果没有,您需要非常清楚您的文件夹/文件结构才能获得有意义的答案。
  • 非常感谢!我唯一需要更改的是在 os.rename 中添加文件夹。 os.rename(join(path, folder, image), join(path, folder, new_image))
猜你喜欢
  • 1970-01-01
  • 2015-04-18
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2016-08-05
  • 1970-01-01
相关资源
最近更新 更多