【问题标题】:How to search for file in folder containing specific text and rename that file in Python如何在包含特定文本的文件夹中搜索文件并在 Python 中重命名该文件
【发布时间】:2020-12-03 21:59:51
【问题描述】:

我正在尝试查找包含我使用列表传递的特定文本的文件名。我已经能够找到这些文件,但我似乎无法重命名它们。我不确定我做错了什么,所以任何帮助都将不胜感激。在 python 方面很新,所以只是尝试通过一些简单的任务来学习。

from os import rename, listdir
import fnmatch

i = 0
divisions = ['BAT','FAB','HIN','OFA','SBY','VAL',
             'FRE','JEF','OLA','SPR','WEB','CTV',
             'MOB','PET','SWN','DEN','GRE','MTJ',
             'ROS','SXB','DWT','HAI','OAK','RPB','TUL']

divs = listdir('.')
ending = " Financials.xlsx"

for div in divs:
    if fnmatch.fnmatch(div, divisions[i]):
        rename(div, divisions[i] + ending)
    i += 1

【问题讨论】:

  • 出了什么问题? if 是否找到文件?重命名是否运行没有错误?由于我们没有您的文件名,因此很难猜出问题所在。该目录中的文件是否有标准格式?您可以运行一些测试,例如 fnmatch.fnmatch("BAT Financials.xlsx", "BAT") 不匹配。
  • 对不起,我不清楚。所以脚本运行没有错误,但文件名没有改变。例如,包含“BAT”的文件名为“BAT Financials 2020.xls”。我正在尝试将其更改为“BAT Financials.xlsx”。但是其他一些文件名中包含其他文本,例如:“2020”、“KPI”、“October”。它们都包含一个标签,表明它们来自哪里,例如“BAT”,但我想将它们全部更改为统一的,例如“BAT Financials.xlsx”,因此 [Divisions] + 结尾。我不确定我是否正确地喂它。我的理论是找到一个具有匹配分割字符串的文件名,然后更改它。
  • 太棒了!您的代码有几个问题,其中之一是您没有在 fnmatch 中包含通配符,因此没有任何匹配项。由于您知道所需文件的确切名称,因此不需要 fnmatch。而你的 for 循环比较了错误的东西。我会写一个答案。
  • 太棒了!非常感谢@tdelaney!是的,我认为它与通配符有关,但我认为这可能是我的 for 循环不正确。

标签: python filenames


【解决方案1】:

您的代码存在两个问题。首先,fnmatch 模式需要一个通配符来匹配文件名。其次,您只比较每个文件名的 1 个divisions 值,当您需要遍历所有文件名直到找到匹配项时。修复这些会为您提供以下内容(我重命名了几个值,因为在文件列表为“divs”时有一个名为“divisions”的东西有点令人困惑)

from os import rename, listdir
from fnmatch import fnmatch

divisions = ['BAT','FAB','HIN','OFA','SBY','VAL',
             'FRE','JEF','OLA','SPR','WEB','CTV',
             'MOB','PET','SWN','DEN','GRE','MTJ',
             'ROS','SXB','DWT','HAI','OAK','RPB','TUL']

# build (division name, fnmatch pattern) for each division
patterns = [(division, f"{division} Financials*.xlsx") for division in divisions]

filenames = listdir('.')

for filename in filenames:
    for division, pattern in patterns:
        if fnmatch(filename, pattern):
            rename(filename, f"{division} Financials.xlsx")
            break

如果您想将其具体限制在 2020 年,则模式会发生变化。事实上,您根本不需要 fnmatch,因为您知道确切的文件名。

from os import rename, listdir

divisions = ['BAT','FAB','HIN','OFA','SBY','VAL',
             'FRE','JEF','OLA','SPR','WEB','CTV',
             'MOB','PET','SWN','DEN','GRE','MTJ',
             'ROS','SXB','DWT','HAI','OAK','RPB','TUL']
filename_map = dict(f"{division} Financials 2020.xlsx":f"{division} Finanacials.xlsx" 
    for division in divisions)

filenames = listdir('.')

for filename in filenames:
    mapped = filename_map.get(filename)
    if mapped:
        rename(filename, mapped)

【讨论】:

  • 你摇滚!如果我只想在 {division} 上使用 fnmatch 模式,我会省略“Financials.xlsx”。因为我想捕获包含该单词的任何文件名。
  • 是的。您可以打开 python shell 并练习fnmatch("BAT something.else", "BAT *") 之类的模式,看看会发生什么。
猜你喜欢
  • 2014-08-11
  • 1970-01-01
  • 2023-03-19
  • 2020-02-08
  • 2021-08-08
  • 1970-01-01
  • 2012-10-18
  • 2021-10-21
  • 2014-03-05
相关资源
最近更新 更多