使用 Python 重命名给定目录中的所有 xml 文件

Rename all xml files within a given directory with Python

我有很多 xml 个文件,它们的名称如下:

First_ExampleXML_Only_This_Should_Be_Name_20211234567+1234565.xml
Second_ExampleXML_OnlyThisShouldBeName_202156789+55684894.xml
Third_ExampleXML_Only_This_Should_Be_Name1_2021445678+6963696.xml
Fourth_ExampleXML_Only_This_Should_Be_Name2_20214567+696656.xml

我必须制作一个脚本来遍历所有文件并重命名它们,所以示例中只剩下这个:

Only_This_Should_Be_Name.xml
OnlyThisShouldBeName.xml
Only_This_Should_Be_Name1xml
Only_This_Should_Be_Name2.xml

目前我有这样的东西,但真的很难得到我需要的东西,我猜必须从秒数 _ 到 _202,然后把中间的所有东西都拿走。

fnames = listdir('.')
for fname in fnames:
    # replace .xml with type of file you want this to have impact on
    if fname.endswith('.xml):

有人知道最好的方法是什么吗?

这里有两个问题:

在目录中找到一种文件

虽然 listdir 可以工作,但您也可以将它们 glob:

from pathlib import Path

for fn in Path("/path").glob("*.xml"):
    ....

正在重命名文件

在这种情况下,您的文件名为“file_name_NUMBERS.xml”,我们想去掉数字,因此我们将使用正则表达式:编辑:这不是最好的方法这个案例。就像其他答案一样拆分和组合

import re
from pathlib import Path
for fn in Path("dir").glob("*.xml"):
    new_name = re.search(r"(.*?)_[0-9]+", fn.stem).group(1)
    fn.rename(fn.with_name(new_name + ".xml"))

编辑: 不知道为什么我把事情搞得太复杂了。对于更困难的情况,我将把 re 解决方案留在那里,但在这种情况下,您可以这样做:

new_name = "_".join(fn.stem.split("_")[:-1])

这是非常优越的,因为它不依赖于文件的精确命名。

请注意,您可以在没有 pathlib 的情况下完成所有这些操作,但您要求的是 最佳 方式 ;)

最后,要回答一个隐含的问题,没有什么能阻止您将所有这些包装在一个函数中,并将参数传递给 glob 以获取不同类型的文件。

您可以通过对所有 xml 文件使用下划线拆分来删除内容,并使用列表中的第一个值重命名,如下所示。

import os

fnames = os.listdir('.')
for fname in fnames:
    # replace .xml with type of file you want this to have impact on
    if fname.endswith('.xml'):
        newName = '_'.join(fname.split("_")[2:-1])
        os.rename(fname, newName+".xml")
    else:
        continue

此处您要删除“_”前后的值。

我认为正则表达式将是这里最简单的方法,在 python 中可以使用 re 模块完成。

import os
import re

fnames = os.listdir('.')
for fname in fnames:
    result = re.sub(r"^.*?_ExampleXML_(.*?)_[\d+]+\.xml$", r".xml", fname)
    if result != fname:
       os.rename(fname, result) 

根据您的用例,您可以采用多种模式匹配策略。

例如,您可以尝试以下变体,具体取决于您需要如何 specific/general: