在Linux中忽略glob()的大小写

58 投票
12 回答
46876 浏览
提问于 2025-04-17 06:26

我正在写一个脚本,这个脚本需要在一些文件夹中工作,这些文件夹的内容是Windows和Linux用户手动修改的。Windows用户通常对文件名的大小写不太在意。

请问在Linux环境下,有没有办法在Python中处理这个问题,也就是说,我能不能实现一种不区分大小写的、类似于通配符的功能?

12 个回答

9

非递归方式

为了获取一个目录“路径”下的文件(仅限文件),可以使用“通配符表达式”:

list_path = [i for i in os.listdir(path) if os.path.isfile(os.path.join(path, i))]
result = [os.path.join(path, j) for j in list_path if re.match(fnmatch.translate(globexpression), j, re.IGNORECASE)]

递归方式

使用 walk 方法:

result = []
for root, dirs, files in os.walk(path, topdown=True):
    result += [os.path.join(root, j) for j in files \
        if re.match(fnmatch.translate(globexpression), j, re.IGNORECASE)]

最好先编译正则表达式,所以可以用下面的方式:

re.match(fnmatch.translate(globexpression)

在循环之前这样做:

reg_expr = re.compile(fnmatch.translate(globexpression), re.IGNORECASE)

然后在循环中进行替换:

result += [os.path.join(root, j) for j in files if re.match(reg_expr, j)]
62

你可以通过下面的方法,把每个字母字符 c 替换成 [cC] 的形式。

import glob
def insensitive_glob(pattern):
    def either(c):
        return '[%s%s]' % (c.lower(), c.upper()) if c.isalpha() else c
    return glob.glob(''.join(map(either, pattern)))
35

使用不区分大小写的正则表达式,而不是通配符模式。fnmatch.translate 可以把通配符模式转换成正则表达式,所以

re.compile(fnmatch.translate(pattern), re.IGNORECASE)

这会给你一个不区分大小写的通配符模式,作为一个编译好的正则表达式。

要记住的是,如果文件系统是在一个类Unix的Linux系统上,用户可以在同一个目录下创建文件 fooFooFOO,它们是可以共存的。

撰写回答