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)