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

Dry*_*ong 34 python

我有一个文件目录,我试图使用Python解析.如果它们都是相同的扩展名,我就不会有问题,但无论出于何种原因,它们都是在原始扩展后使用顺序数字扩展创建的.例如:foo.log foo.log.1 foo.log.2 bar.log bar.log.1 bar.log.2 etc.最重要的是,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')
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为它不读取任何.log.*文件,并且解析器在读取的文件上阻塞,但不是xml格式.谢谢!

str*_*nac 72

也许glob模块可以帮助你:

import glob

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

  • 如果OP期望它像Windows“cmd”shell中的通配符而不是POSIX shell中的通配符一样工作,那么它并不是很完美......但对于他的用例来说它应该足够好,并且很可能对于他将要出现的任何用例跟上了,所以我认为这是正确的答案。 (2认同)

aba*_*ert 11

为了只读取和解析文件foo.log.*foo.log文件,最佳路径是什么?不需要读取bar.log文件.

您的代码执行此操作:

if files.endswith('.log'):
Run Code Online (Sandbox Code Playgroud)

你刚刚将你的英文描述翻译成Python有点不对劲.你在Python中写的是:"只读取和解析*.log文件",意思bar.log是包括在内,而foo.log.1不是.

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

if files == 'foo.log' or files.startswith('foo.log.'):
Run Code Online (Sandbox Code Playgroud)

如果你考虑一下,只要没有foo.log.你想要跳过的文件(带有那个额外的点),你就可以将这两个案例合并为一个:

if files.startswith('foo.log'):
Run Code Online (Sandbox Code Playgroud)

但是,如果你对POSIX shell有所了解,那么foo.log*匹配完全相同.(对于Windows shell而言,情况并非如此,其中通配符专门处理扩展,这就是为什么你必须键入*.*而不是*.)并且Python附带了一个模块,它可以执行POSIX样式的通配符,甚至在Windows上也可以调用glob.请参阅stranac的答案,了解如何使用它.

我认为glob答案比手动过滤更好listdir.它更简单,它更直接匹配你的问题标题你想要做什么(只是做你希望的工作os.listdir,但glob.glob相反),它更灵活.所以,除非你担心被两个略有不同的通配符含义搞糊涂,否则我建议接受这个而不是这个.


dst*_*erg 5

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

import glob
print(glob.glob("/tmp/o*"))
Run Code Online (Sandbox Code Playgroud)

或者,您可以在整个目录中使用os.listdir,然后通过re模块丢弃与正则表达式不匹配的文件。