Python 在os.listdir(path)中使用文件扩展名通配符

Python 在os.listdir(path)中使用文件扩展名通配符,python,Python,我有一个我正试图用Python解析的文件目录。如果它们都是相同的扩展名,我就不会有问题,但不管出于什么原因,它们都是在原始扩展名之后使用顺序数字扩展名创建的。例如:foo.log foo.log.1foo.log.2bar.log bar.log.1bar.log.2等。除此之外,foo.log是XML格式,而bar.log不是。为了只读取和解析foo.log.*和foo.log文件,最好的方法是什么?不需要读取bar.log文件。下面是我的代码: import os from lxml imp

我有一个我正试图用Python解析的文件目录。如果它们都是相同的扩展名,我就不会有问题,但不管出于什么原因,它们都是在原始扩展名之后使用顺序数字扩展名创建的。例如:
foo.log foo.log.1foo.log.2bar.log bar.log.1bar.log.2等。
除此之外,foo.log是XML格式,而bar.log不是。为了只读取和解析
foo.log.*
foo.log
文件,最好的方法是什么?不需要读取
bar.log
文件。下面是我的代码:

import os
from lxml import etree
path = 'C:/foo/bar//'
listing = os.listdir(path)
for files in listing:
    if files.endswith('.log'):
        print files
        data = open(os.path.join(path, files), 'rb').read()
        tree = etree.fromstring(data)
        search = tree.findall('.//QueueEntry')
这不起作用,因为它不读取任何
.log.*
文件,解析器会阻塞已读取但不是xml格式的文件。谢谢

也许模块可以帮助您:

import glob

listing = glob.glob('C:/foo/bar/foo.log*')
for filename in listing:
    # do stuff

这将为您提供类似bash的正则表达式:

import glob
print(glob.glob("/tmp/o*"))
或者,您可以使用os.listdir访问整个目录,并通过re模块丢弃与正则表达式不匹配的文件

为了只读取和解析
foo.log.*
foo.log
文件,最好的方法是什么?不需要读取bar.log文件

您的代码执行以下操作:

if files.endswith('.log'):
您刚刚将英语描述翻译成Python有点错误。用Python编写的代码是:“只读取和解析
*.log
文件”,这意味着包含
bar.log
,而不包含
foo.log.1

但如果您想一想,可以将您的英文描述直接翻译成Python:

if files == 'foo.log' or files.startswith('foo.log.'):
如果您仔细想想,只要没有名为
foo.log.
(带有该额外点)的文件要跳过,就可以将这两个案例合并为一个:

if files.startswith('foo.log'):
但是,如果您了解POSIX shell,
foo.log*
与之完全匹配。(对于Windows Shell,这是不正确的,因为通配符特别处理扩展,这就是为什么您必须键入
*.
而不是
*
),Python附带了一个模块,即使在Windows上也可以执行POSIX样式的通配符,称为
glob
。有关如何使用此选项,请参见stranac的答案


我认为
glob
答案比手动过滤
listdir
要好。更简单的是,它更直接地符合您的问题标题所说的您想要做的事情(只需完全按照您希望的方式使用
os.listdir
,而使用
glob.glob
),而且它更灵活。因此,除非您担心被通配符的两个稍有不同的含义弄糊涂,否则我建议您接受这一点,而不是这一点。

正如前面提到的那样:您可以使用glob.glob来查找使用通配符的文件。
我不能写评论,这是一个很老的问题,但是。。。有人建议,glob.glob不能在路径中扩展。因此,您可以使用os.path.expanduser进行扩展,并使用os.path.expandvars来扩展环境变量。

如果OP希望它像Windows
cmd
shell中的通配符一样工作,而不是POSIX shell,那么它并不十分完美……但对于他的用例来说,它应该足够好了,而且很可能适用于他将要提出的任何用例,所以我认为这是正确的答案。感谢glob没有扩展
~
-不知何故,Python使所有的系统命令都比unix更糟糕…完美!虽然对于路径(因为它是Windows),我更喜欢:r“'C:\foo/\bar\foo.log*Glob通配符不是正则表达式。从技术上讲,它是一种常规语言,但人们说“regex”时并不是这么想的,bash文档明确地说它不是正则表达式。
/tmp/o*
并不意味着”
/tmp/
后接0个或多个
o
”实例。请参阅。我很久以前在comp.unix.shell上了解到,*ix有多种正则表达式,包括glob模式。高级Bash脚本指南“不是bash文档的一部分-它是由一个perl狂热者编写的,他可能认为perl正则表达式是任何人都应该使用的唯一正则表达式。它没有说“正则表达式”,或者任何类似的东西。这是。它明确定义了两种可算作正则表达式的语言(BRE和ERE)。您可以在
bash
linux
/
glibc
*BSD
等文档中找到类似的措辞。