当前位置: 首页 > 知识库问答 >
问题:

使用os.walk更改图像名称以包括父目录名称

林玮
2023-03-14

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

文件夹名称:ABCDEF-这是-我的文件夹-名称

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

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

共有1个答案

时修贤
2023-03-14

好的,我读了你的问题,我想我知道怎么了。

1.)迭代的os.walk()是递归的,也就是说,如果您使用os.walk(r'C:\'),它将循环遍历所有文件夹并找到C驱动器下的所有文件。现在我不确定您的C:\folderPath中是否有任何子文件夹。如果是这样,并且任何文件夹/文件格式都不是C:\folderPath的约定,您的代码将会有一个不好的时间。

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

3.)您已经从os.path导入了join,但最终还是调用了os.path.join()的全名,这是多余的。只需导入操作系统并调用os.path.join(),或者只需使用当前导入的操作系统join()。

说到这里,以下是我的编辑:

如果您的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.

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

从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()是一个非常好的iterables工具,它还提供了迭代次数。

2.)您的split()。在您的例子中,image是实际的文件名,files是当前迭代目录中的文件列表。

3.)使用str.format()。

4.)您会注意到使用了split(\\”而不是split(r“\”,这是因为单个反斜杠不能是原始字符串。

这现在应该行得通了。我最终做了比预期更多的研究,比如如何在这两种场景中正确处理os.walk()。作为将来的参考,一点谷歌搜索会大有帮助。我希望这最终回答了你的问题。记住,做你自己的研究和清晰地展示你的问题会给你更有效的答案。

好处:如果你有python 3.6,你甚至可以使用f字符串作为你的新文件名,这最终看起来很酷:

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

 类似资料:
  • 如何在Android Studio 0.9.9中更改项目根目录的名称。我在这里阅读了其他解决方案,但对我来说没有任何效果。我可以更改/重构包名称,但不能更改根目录的名称。我在这里找到了另一个解决方案,即更改文件中的名称,但没有成功。更改名称后,我尝试了清理、重建等,但没有任何东西反映Android Studio中的更改。“PROJECT NAME/ROOT DIRECTORY NAME”没有REF

  • 我有一个应用程序,我想重新品牌。这是我的共享意图代码: 知道哪里出了问题吗? 提前道谢。

  • 问题内容: 我使用FlexJson进行序列化,唯一的问题是它会生成小写的字段名,而我需要它们以大写开头: 当序列化时,字段被序列化为,而我需要它被序列化。 如何指定输出字段名称?我可以使用一些属性来指定所需的序列化名称吗? 问题答案: 您可以使用“ 自定义变压器” 来实现。根据Flexjson页面转换器是: 负责确定如何将传入的对象转换为JSON,对JSONContext对象进行适当的调用以输出J

  • 问题内容: 我有一个来自外部来源的jar文件。jar中的所有类都在com.xyz包中。 我想将所有类都移到com.xyzold包中。 这是简单的操作,例如解压缩jar,将xzy文件夹重命名为xyzold并重新压缩它,还是我还需要修改每个类文件? 这是我的解决方案,使用Jar Jar Links 这是我的rules.txt文件的内容: 问题答案: 您可以使用Jar Jar Links 来实现。同样,

  • 问题内容: 我有一个必须在单个物理框中运行多个tomcat服务器的要求。从浏览器访问这些文件时,当用户在应用程序之间切换时,将导致注销用户先前访问的应用程序。这是因为JSESSIONID Cookie冲突。 一种可能的解决方案是在不同的上下文中运行每个应用程序。不幸的是,我的应用程序无法在上下文路径设置中工作,因为前面没有使用request.getContextPath()访问任何资源。 这使我可

  • 到目前为止我所尝试的: > 在Docusign管理设置(设置->签名设置->签名采用配置)中,禁用了“锁定收件人名称”复选框,但这不会导致任何更改。 我还尝试在API中的签名者(https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/enveloperecipients/#core-recipitions-pa