ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

xonsh 文件通配(Globbing)完全指南:普通通配、正则通配与 Match 通配实战

xonsh 文件通配(Globbing)完全指南:普通通配、正则通配与 Match 通配实战 开发工具【免费下载链接】xonsh Python-powered shell. Full-featured, cross-platform and AI-friendly.项目地址https://gitcode.com/gh_mirrors/xo/xonsh点击查看免费下载本文是 xonshPython-powered shell官方文档 docs/globbing.rst 的深度展开系统讲解 xonsh 支持的四种文件名匹配方式——普通shell 风格通配、正则表达式通配、Match 通配与格式化通配字面量并逐一剖析$DOTGLOB、$GLOB_SORTED环境变量及XonshList链式 API 的底层实现对应源码见 xonsh/built_ins.py、xonsh/tools.py 与 xonsh/environ.py。读完本文你将掌握在子进程模式与 Python 模式中自由组合g、r、m、f 等通配语法直接解构路径、提取捕获组并写出可复用的链式文件处理管道。总览xonsh 的四种通配形式xonsh 支持四种形式的文件名通配globbing普通通配Normal Globbingshell 风格的*、?、[...]、**底层基于 Python 标准库glob模块正则表达式通配Regular Expression Globbing用反引号包裹正则表达式来匹配文件名Match 通配Match Globbing正则通配的变体返回捕获组而非完整路径格式化通配字面量Formatted Glob Literals在通配模式中插入变量与表达式。以上所有形式既可以用于子进程模式也可以用于 Python 模式返回结果均为XonshListlist的子类带有一系列便捷方法。普通通配Normal Globbing在子进程模式中*字符的普通文件名通配无需任何特殊语法即可生效底层由 Python 的glob模块实现。先构造一个测试目录 mkdir -p test/a/b touch test/f.txt test/a/f.txt test/a/b/f.txt ls test a f.txt在子进程模式下直接使用* ls test/*.txt test/f.txt如果需要在 Python 模式以及子进程模式中也使用普通通配可以用g前缀的反引号语法 print(gtest/*.txt) [test/f.txt]通配符语义*匹配单个路径分量component内的任意字符?匹配单个字符[abc]匹配方括号内列举的任意一个字符**递归通配匹配零个或多个中间目录。例如test/**/f.txt可以同时匹配test/f.txt、test/a/f.txt和test/a/b/f.txt print(gtest/**/f.txt) [test/a/b/f.txt, test/a/f.txt, test/f.txt]源码视角普通通配的底层实现普通通配在 Python 模式下经由globsearch完成xonsh/built_ins.py它读取$GLOB_SORTED与$DOTGLOB两个环境变量并调用 xonsh/tools.py 中的globpath()def globsearch(s): glob_sorted XSH.env.get(GLOB_SORTED) dotglob XSH.env.get(DOTGLOB) return XonshList( globpath( s, ignore_caseTrue, return_emptyTrue, sort_resultglob_sorted, include_dotfilesdotglob, ) )值得注意的是ignore_caseTruexonsh 的普通通配默认大小写不敏感。此外xonsh/tools.py 中的_case_insensitive_iglob实现了逐段segment-by-segment的大小写不敏感遍历并刻意容忍os.listdir抛出的PermissionError例如 Android/Termux 这类沙箱环境下/根目录不可枚举的场景让cd /data/data/...依然能正常补全。隐藏文件Dot Files与$DOTGLOB默认情况下通配会排除隐藏文件与隐藏目录——即名称以字面.开头的条目。$DOTGLOB环境变量统一控制所有通配形式普通通配g、正则通配r以及子进程模式下的裸通配符。该变量定义于 xonsh/environ.py默认值为False touch visible .hidden print(g*) [visible]当$DOTGLOB设为True时隐藏文件被纳入匹配 $DOTGLOB True print(g*) [.hidden, visible]正则通配同样受此变量约束 $DOTGLOB True print(\..*) [.hidden]从源码看$DOTGLOB在globsearch、regexsearch、regexmatchsearch三处统一生效xonsh/built_ins.py保证了「所有通配形式行为一致」。补充一个文档未展开的细节在_case_insensitive_iglob的实现中xonsh/tools.py如果一个段显式以.开头如字面.foo或通配.x*则被视为明确请求隐藏名称不再应用 dotfile 过滤——这与 Python 标准库glob的行为保持一致只有裸通配*、**、foo*在$DOTGLOB为False时才隐藏 dotfiles。正则表达式通配Regular Expression Globbing如果觉得普通通配不够“带劲”正则通配正是你需要的工具。任何使用反引号而非引号、包裹的字符串都会被解释为用于匹配文件名的正则表达式。与普通通配一样它返回匹配结果列表在 Python 模式中是字符串列表在子进程模式中每个文件名会成为子进程命令的一个独立参数。反引号前加r前缀执行的是完全相同的搜索因此下面的写法等价test与rtest。 touch a aa aaa aba abba aab aabb abcba ls a(a|b)a aaa aba abba print(a(a|b)a) [aaa, aba, abba]逐段匹配Segment-by-Segment Matching原理正则通配的实现为 xonsh/built_ins.py 中的reglob()。它按路径分隔符/将模式切分然后把每一段单独编译为正则表达式在每一层目录只访问与当前段匹配的条目从而提前剪枝目录树避免整树递归遍历parts tail.split(os.sep) ... regex re.compile(parts[i])这种剪枝设计带来了一个重要限制跨越/的正则特性会失效因为拆开后的每一段自身不再是合法的正则。例如 # 分组跨 / —— 每一段都留下一个未闭合的括号 r(.*/)*\w\.py re.error: missing ), unterminated subpattern at position 0 # 反向引用跨 / —— 引用了另一个段中的分组 r(\w)/(\1)\.py re.error: cannot refer to an open group at position 8reglob()在捕获到re.error时会抛出带有明确指引的XonshErrorxonsh/built_ins.py提示「正则通配按/拆分、分组与反向引用不能跨越/」。若确有跨段需求可改用下文介绍的m通配或自定义搜索函数。格式化通配字面量Formatted Glob Literals在正则通配或普通通配上使用f修饰符可以让通配模式表现得像格式化字符串字面量f-string从而把变量和其他表达式代入模式中 touch a aa aaa aba abba aab aabb abcba mypattern ab print(f{mypattern[0]}) [a, aa, aaa] print(gf{mypattern}*) [aba, abba, abcba]可以看到f前缀单独使用 格式化的正则通配f{mypattern[0]}等价于正则agf组合前缀 格式化的普通通配gf{mypattern}*等价于gab*。这非常适合把动态构造的变量注入通配模式实现“模式即表达式”。Match 通配Match Globbingm修饰符开启match globbing——一种返回捕获组而非完整路径的正则通配让你可以直接解构匹配到的路径 for parent, file in m.*/(.*)/(.*\.py): print(parent, file) src main.py src utils.py tests test_main.py匹配规则当模式中包含捕获组()时每个匹配返回一个捕获字符串组成的元组没有捕获组时返回完整路径——与r通配结果相同但使用全路径匹配而非逐段匹配。这对于提取路径组成部分极为有用免去手动 split # 找出所有 .png 文件并得到 (目录, 文件名) 对 pairs mimages/(.*)/(.*\.png) print(pairs) [(icons, logo.png), (photos, cat.png)] # 单个捕获组 —— 返回扁平字符串列表 names msrc/(.*)\.py print(names) [main, utils]源码视角Match 通配如何工作m通配由 xonsh/built_ins.py 的regexmatchsearch()实现其核心逻辑与r通配完全不同编译整个正则后通过_RE_SPECIAL正则定位静态前缀模式中第一个正则特殊字符之前的部分以此作为os.walk的起点避免从根目录全量扫描对每个条目执行regex.fullmatch(path)——正则作用于完整路径按捕获组数量规整结果无组返回路径字符串单组返回字符串列表多组返回元组列表最终results.sort()保证结果有序。由于m通配将正则应用于全路径分组、反向引用等正则特性可以自由跨越/。同时它同样尊重$DOTGLOB——默认排除隐藏文件与目录regexmatchsearch中显式过滤以.开头的dirs与files。排序与$GLOB_SORTED默认情况下通配结果按字母序排序。$GLOB_SORTED环境变量控制普通通配的排序行为定义于 xonsh/environ.py默认值为True。设为False后结果按文件系统任意顺序返回 $GLOB_SORTED False g* [setup.py, README.md]注意两点正则通配r不受此变量影响始终排序——从reglob()源码可见其对每层files执行了files.sort()xonsh/built_ins.pym通配也在结束时统一results.sort()$GLOB_SORTED仅控制普通g通配globsearch将其作为sort_result参数传入globpath。XonshList可链式调用的通配结果所有通配形式g、r、m以及下文提到的p返回的都是XonshList——list的扩展子类定义于 xonsh/built_ins.py为常见的 shell 操作提供便捷方法。每个方法都返回一个新的XonshList因此调用可以无限链式串联 g**/*.py.files().sorted() [setup.py, src/main.py, tests/test_main.py] r.*\.log.exists().paths() [PosixPath(app.log), PosixPath(error.log)] msrc/(.*)\.py.unique().sorted() [config, main, utils]可用方法一览方法说明.sorted(key, reverse)返回新的排序列表。不同于list.sort()它返回列表本身以便链式调用.unique()去重并保持原有顺序.filter(func)仅保留func(elem)为真值的元素.select(n)从每个元组中取出第 n 个元素用于多捕获组的m通配跳过可选组产生的None.paths()将元素转换为pathlib.Path对象.files()仅保留存在的常规文件.dirs()仅保留存在的目录.exists()仅保留磁盘上真实存在的路径.visible()仅保留可见非隐藏条目.hidden()仅保留隐藏条目Unix 上的 dotfileWindows 上为FILE_ATTRIBUTE_HIDDEN更完整的示例——找出所有 Python 测试文件转换为Path对象并仅提取文件名 gtests/**/*.py.files().paths().filter(lambda p: p.stem.startswith(test_)) [PosixPath(tests/test_main.py), PosixPath(tests/test_utils.py)]源码视角XonshList 的设计XonshList的实现细节值得留意链式保证unique()使用dict.fromkeys去重xonsh/built_ins.pysorted()调用内置sorted而非list.sort()xonsh/built_ins.py确保每次都返回新对象跨平台隐藏文件判定_is_hiddenxonsh/built_ins.py在 Unix 上检查名称是否以.开头在 Windows 上进一步读取FILE_ATTRIBUTE_HIDDEN属性相关单元测试见 tests/test_xonsh_list.py覆盖了去重保序、select跳过None、元组拒绝路径方法、链式返回类型等行为通配在真实子进程/ Python 模式下的集成用例可参考 tests/api/test_subprocess.xsh。处理 Match 通配产生的元组当m通配含多个捕获组时结果是元组列表。基于路径的方法.files()、.dirs()、.exists()、.paths()无法直接处理元组——必须先用.select(n)取出具体元素 results msrc/(.*)/(.*\.py) print(results[:2]) [(lib, utils.py), (lib, main.py)] results.files() # TypeError! TypeError: .files() requires string paths, got tuples. Use .select(n) to pick a tuple element first, e.g. .select(0).files() # 提取目录名 results.select(0).unique().sorted() [lib, tests] # 提取文件名 results.select(1).sorted() [main.py, utils.py]这个错误提示由XonshList._check_paths主动抛出xonsh/built_ins.py并直接给出修复建议。而不依赖路径的方法——.unique()、.sorted()、.filter()——可以直接作用于元组 msrc/(.*)/(.*\.py).unique().sorted()[:3] [(lib, main.py), (lib, utils.py), (tests, test_main.py)]由于XonshList是常规list的子类它在任何列表可用之处都能工作——迭代、索引、len()、传给函数等均与普通列表无异。进阶通过自定义搜索实现全路径正则xonsh 支持用funcpattern 语法挂载自定义路径搜索函数。借助它可以轻松实现“正则应用于整个路径、而非按/拆分”的全路径匹配 def refullglob(pattern): import re, os regex re.compile(pattern) results [] for root, dirs, files in os.walk(.): for name in dirs files: path os.path.join(root, name) if regex.fullmatch(path): results.append(path) return results refullglob(.*/)*\w\.py [./src/main.py, ./src/utils.py, ./tests/test_main.py]pathsearch()xonsh/built_ins.py会校验搜索函数可调用且仅接受一个参数再将其用于路径匹配regexsearch、globsearch等内置搜索函数与自定义函数共用同一套调用约定。与内置r通配相比自定义搜索有明显的权衡优点完整的re语法可用——分组、反向引用、交替可以跨越/缺点总是遍历整棵目录树。在大目录树上这比内置的逐段剪枝慢得多缺点$DOTGLOB不会被自动尊重——如需要排除隐藏条目请自行过滤以.开头的名称。小结与速查语法语义返回*/?/[abc]/**子进程模式普通通配每个匹配成为命令的一个参数gpat普通通配Python 模式可用XonshList默认大小写不敏感regex/rregex正则通配逐段匹配XonshList始终排序f{expr}regex/gf{expr}glob格式化通配支持代入变量与表达式mregexMatch 通配全路径匹配无组返回路径单组返回字符串多组返回元组funcpattern自定义路径搜索完全自定义关键环境变量$DOTGLOB默认False控制隐藏文件是否参与所有通配形式与$GLOB_SORTED默认True仅控制普通通配是否排序。结合XonshList的.files()、.paths()、.select()、.unique()等方法你可以在单行表达式中完成“匹配 → 过滤 → 转换 → 排序”的完整文件处理流水线。赞分享开发工具【免费下载链接】xonsh Python-powered shell. Full-featured, cross-platform and AI-friendly.项目地址https://gitcode.com/gh_mirrors/xo/xonsh点击查看免费下载相关推荐mcp-use TypeScript 实战示例全解析从最小 MCP 服务器到 MCP Apps 交互式视图mcp use TypeScript 实战示例全解析从最小 MCP 服务器到 MCP Apps 交互式视图 mcp use 是一个面向 AI Agent 的全后端MCP 服务MCP ClientsAI Agent人工智能MNE-Python完全指南从脑磁图脑电图数据处理到源定位分析MNE Python完全指南从脑磁图脑电图数据处理到源定位分析 MNE Python是一个强大的开源Python软件包专门用于探索、可视化和分析人类神经生理科学计算数据分析数据可视化科研MinIO事件通知精准匹配规则配置与实战指南MinIO事件通知精准匹配规则配置与实战指南 你是否在配置MinIO事件通知时遇到过规则匹配混乱、通知触发异常的问题本文将系统解析MinIO事件通知的精确匹后端存储对象存储分布式存储云原生创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表