我有一个文件夹,其中包含5个文件,分别名为' out1.jpg ',' out2a.jpg ',' out2b.jpg ' ,“ out3.jpg ”和“ out4.jpg ”以及其他格式不同的文件。 我有这个Python脚本,应该可以打印所有匹配的文件名:
import fnmatch
import os
c = 1
for file in os.listdir('.'):
if fnmatch.fnmatch(file, 'out'+str(c)+'*.jpg'):
print(file)
c +=1
但是,当我运行此脚本时,输出限于以下内容:
out1.jpg
out2a.jpg
out3.jpg
任何人都对如何更改脚本以显示所有匹配的文件名(这是我提到的5个文件名)有一个想法?
答案 0 :(得分:4)
您在每次迭代中增加c
(嗯,无论如何,每次迭代都找到了匹配项……),因此显然不能匹配“ out2a.jpg”和“ out2b.jpg”。假设您希望所有匹配“ out” +一些数字+最后是其他名称的文件名,则可以使用字符范围;即:
for file in os.listdir('.'):
if fnmatch.fnmatch(file, 'out[0-9]*.jpg'):
print(file)
注意:您可能需要根据需要和目录中的内容来调整确切的fnmatch模式。
您也可以改用glob.glob
,它既简单又高效(根据文档):
import glob
for file in glob("out[0-9]*.jpg"):
print(file)
编辑:
我完全理解为什么它不能同时显示out2a.jpg和out2b.jpg,但是我不明白为什么不显示out4.jpg!
很简单,因为os.listdir()
不一定按您期望的顺序返回文件名(在我的Linux工作站上,“ out4.jpg”位于其他“ outXXX.jpg”文件之前)。您只需添加几个打印件即可查看正在发生的情况:
c = 1
for file in os.listdir('.'):
exp = 'out{}*.jpg'.format(c)
print("file: {} - c : {} - exp : {}".format(file, c, exp))
if fnmatch.fnmatch(file, exp):
print(file)
c +=1
结果在这里:
file: sofnm.py~ - c : 1 - exp : out1*.jpg
file: out4.jpg - c : 1 - exp : out1*.jpg
file: out2b.jpg - c : 1 - exp : out1*.jpg
file: out1.jpg - c : 1 - exp : out1*.jpg
out1.jpg
file: out2a.jpg - c : 2 - exp : out2*.jpg
out2a.jpg
file: sofnm.py - c : 3 - exp : out3*.jpg
file: out42a.jpg - c : 3 - exp : out3*.jpg
file: out3.jpg - c : 3 - exp : out3*.jpg
out3.jpg
如您所见,您认为os.listdir()
将以给定顺序(以“ out1.jpg”开始,以“ out4.jpg”结束)返回文件的假设是错误的。通常,当您的代码无法按预期运行时,跟踪代码执行(及相关值)通常是找出原因的最简单方法。
答案 1 :(得分:2)
您在文件匹配后增加c,很有可能文件名是out2a.jpg,但是c的值为1。因此,它将不匹配。您应该以升序列出所有文件,以便out1在listdir中排在out2之前,或者您应该使用通用数字匹配而不是如下所示的一一对应:
import fnmatch
import os
for file in os.listdir('.'):
#print(file)
if fnmatch.fnmatch(file, 'out[0-9]*.jpg'):
print(file)
答案 2 :(得分:1)
在此for循环中运行时,您要对照非常特定的文件名(首先out1*.jpg
,然后是out2*.jpg
)检查目录中的每个文件,但不能保证这些文件的顺序匹配。例如,当我尝试在本地运行代码时,首先将out2a.jpg与模式out1*.jpg
比较,然后将out2b.jpg与out2*.jpg
比较,然后将test.py
(脚本)与{{ 1}}。
最好使用out3*.jpg
(https://docs.python.org/3/library/glob.html)这样的模块来搜索'out * .jpg':glob
。