fnmatch 不显示所有匹配的文件名
fnmatch does not display all filenames that match
我有一个包含 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 个文件名)吗?
您在每次迭代中增加 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)
编辑:
I totally understand why it does not display out2a.jpg and out2b.jpg together, but I didn't get why out4.jpg is not displayed!
很简单,因为 os.listdir()
不一定 return 文件名的顺序与您预期的顺序相同(在我的 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()
将 return 文件按给定顺序(从 "out1.jpg" 开始并以 "out4.jpg" 结束)是错误的。作为一般规则,当您的代码未按预期运行时,跟踪代码执行(和相关值)通常是找出原因的最简单方法。
运行 通过这个 for 循环,您将根据非常具体的文件名(首先是 out1*.jpg
,然后是 out2*.jpg
)检查目录中的每个文件,但不能保证这些文件的顺序匹配。例如,当我尝试在本地 运行 代码时,它首先将 out2a.jpg 与模式 out1*.jpg
进行比较,然后 out2b.jpg 与 out2*.jpg
,然后 test.py
(脚本)与 out3*.jpg
.
你最好使用像 glob
(https://docs.python.org/3/library/glob.html) 这样的模块来搜索 'out*.jpg': glob.glob('out[0-9]*.jpg')
.
你在文件匹配后递增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)
我有一个包含 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 个文件名)吗?
您在每次迭代中增加 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)
编辑:
I totally understand why it does not display out2a.jpg and out2b.jpg together, but I didn't get why out4.jpg is not displayed!
很简单,因为 os.listdir()
不一定 return 文件名的顺序与您预期的顺序相同(在我的 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()
将 return 文件按给定顺序(从 "out1.jpg" 开始并以 "out4.jpg" 结束)是错误的。作为一般规则,当您的代码未按预期运行时,跟踪代码执行(和相关值)通常是找出原因的最简单方法。
运行 通过这个 for 循环,您将根据非常具体的文件名(首先是 out1*.jpg
,然后是 out2*.jpg
)检查目录中的每个文件,但不能保证这些文件的顺序匹配。例如,当我尝试在本地 运行 代码时,它首先将 out2a.jpg 与模式 out1*.jpg
进行比较,然后 out2b.jpg 与 out2*.jpg
,然后 test.py
(脚本)与 out3*.jpg
.
你最好使用像 glob
(https://docs.python.org/3/library/glob.html) 这样的模块来搜索 'out*.jpg': glob.glob('out[0-9]*.jpg')
.
你在文件匹配后递增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)