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

2024-11-12 08:36:00
admin
原创
22
摘要:问题描述:我正在编写一个脚本,该脚本必须适用于 Windows 和 Linux 用户手动修改的目录。Windows 用户在分配文件名时往往根本不关心大小写。有没有办法在 Python 的 Linux 端处理这个问题,即我是否可以获得不区分大小写的类似 glob 的行为?解决方案 1:您可以将每个字母字符 c ...

问题描述:

我正在编写一个脚本,该脚本必须适用于 Windows 和 Linux 用户手动修改的目录。Windows 用户在分配文件名时往往根本不关心大小写。

有没有办法在 Python 的 Linux 端处理这个问题,即我是否可以获得不区分大小写的类似 glob 的行为?


解决方案 1:

您可以将每个字母字符 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)))

解决方案 2:

使用不区分大小写的正则表达式,而不是 glob 模式。fnmatch.translate从 glob 模式生成正则表达式,因此

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

为您提供一个不区分大小写的 glob 模式版本作为已编译的 RE。

请记住,如果文件系统由类 Unix 文件系统上的 Linux 机器托管,则用户将能够在同一目录中创建文件fooFoo和。FOO

解决方案 3:

非递归

为了检索目录“路径”的文件(且仅文件),使用“globexpression”:

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)]

递归地

步行:

result = []
for root, dirs, files in os.walk(path, topdown=True):
    result += [os.path.join(root, j) for j in files \n        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)]

解决方案 4:

起始价python-3.12,您可以使用将参数设置Path.glob(pattern, *, case_sensitive=None)为的 APIcase_sensitive`False`来获取所需的行为。

默认情况下,或者当case_sensitive仅关键字参数设置为 时
,此方法使用特定于平台的大小写规则匹配路径:通常,在POSIXNone上区分大小写,在Windows上不区分大小写。设置为或可覆盖此行为。case_sensitive`True`False

解决方案 5:

这是我针对 Python 3.5+ 的非递归文件搜索,具有类似 glob 的行为

# Eg: find_files('~/Downloads', '*.Xls', ignore_case=True)
def find_files(path: str, glob_pat: str, ignore_case: bool = False):
    rule = re.compile(fnmatch.translate(glob_pat), re.IGNORECASE) if ignore_case \n            else re.compile(fnmatch.translate(glob_pat))
    return [n for n in os.listdir(os.path.expanduser(path)) if rule.match(n)]

注意:此版本处理主目录扩展

解决方案 6:

根据您的情况,您可能.lower()同时使用文件模式和文件夹列表的结果,然后将模式与文件名进行比较

解决方案 7:

借鉴@Timothy C. Quinn 的回答,此修改允许在路径中的任何位置使用通配符。诚然,这仅对 glob_pat 参数不区分大小写。

import re
import os
import fnmatch
import glob

def find_files(path: str, glob_pat: str, ignore_case: bool = False):
    rule = re.compile(fnmatch.translate(glob_pat), re.IGNORECASE) if ignore_case \n            else re.compile(fnmatch.translate(glob_pat))
    return [n for n in glob.glob(os.path.join(path, '*')) if rule.match(n)]

解决方案 8:

这是一个工作示例fnmatch.translate()

from glob import glob
from pathlib import Path
import fnmatch, re


mask_str = '"*_*_yyww.TXT" | "*_yyww.TXT" | "*_*_yyww_*.TXT" | "*_yyww_*.TXT"'
masks_list = ["yyyy", "yy", "mmmmm", "mmm", "mm", "#d", "#w", "#m", "ww"]

for mask_item in masks_list:
    mask_str = mask_str.replace(mask_item, "*")

clean_quotes_and_spaces = mask_str.replace(" ", "").replace('"', '')
remove_double_star = clean_quotes_and_spaces.replace("**", "*")
masks = remove_double_star.split("|")

cwd = Path.cwd()

files = list(cwd.glob('*'))
print(files)

files_found = set()

for mask in masks:
    mask = re.compile(fnmatch.translate(mask), re.IGNORECASE)
    print(mask)

    for file in files:        
        if mask.match(str(file)):
            files_found.add(file)         

print(files_found)

解决方案 9:

我只是想要一个变体,如果我指定文件扩展名,我只会不区分大小写 - 例如,我希望“.jpg”和“.JPG”被同样抓取。这是我的变体:

import re
import glob
import os
from fnmatch import translate as regexGlob
from platform import system as getOS

def linuxGlob(globPattern:str) -> frozenset:
    """
    Glob with a case-insensitive file extension
    """
    base = set(glob.glob(globPattern, recursive= True))
    maybeExt = os.path.splitext(os.path.basename(globPattern))[1][1:]
    caseChange = set()
    # Now only try the extended insensitivity if we've got a file extension
    if len(maybeExt) > 0 and getOS() != "Windows":
        rule = re.compile(regexGlob(globPattern), re.IGNORECASE)
        endIndex = globPattern.find("*")
        if endIndex == -1:
            endIndex = len(globPattern)
        crawl = os.path.join(os.path.dirname(globPattern[:endIndex]), "**", "*")
        checkSet = set(glob.glob(crawl, recursive= True)) - base
        caseChange = set([x for x in checkSet if rule.match(x)])
    return frozenset(base.union(caseChange))

我实际上并没有将不敏感性限制在扩展上,因为我很懒,但是混淆空间非常小(例如,你想捕获FOO.jpgFOO.JPG不想捕获 foo.JPGfoo.jpg;如果你的路径是病态的,你就会遇到其他问题)

解决方案 10:

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)))

也可以是:

def insensitive_glob(pattern):
    return glob.glob(
        ''.join([
            '[' + c.lower() + c.upper() + ']'
            if c.isalpha() else c
            for c in pattern
        ])
    )

解决方案 11:

使用名称文件递归搜索来改变您的答案:

def insensitive_for_glob(string_file):
    return ''.join(['[' + c.lower() + c.upper() + ']' if c.isalpha() else c for c in string_file])

在代码的其他地方:

namefile = self.insensitive_for_glob(namefile)
lst_found_file = glob.glob(f'{file_path}/**/*{namefile}', recursive=True)

解决方案 12:

您可以简单地搜索大写和小写,然后添加结果,如下所示:

from pathlib import Path folder = Path('some_folder')
file_filter = '.txt' 
files_in_folder = [files for files in (
    list(folder.glob(f'*{file_filter.lower()}'))+
    list(folder.glob(f'*{file_filter.upper()}'))
)]

这将找到以.txt.TXT结尾的文件。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用