资讯动态

如何用 Dir.glob 按模式搜索文件并控制 flags 与排序?

发布时间:2026/9/13 2:02:45 来源:尧图企业网站定制
如何用 Dir.glob 按模式搜索文件并控制 flags 与排序【免费下载链接】rubyThe Ruby Programming Language项目地址: https://gitcode.com/GitHub_Trending/ru/ruby任务目标在 Ruby 中用Dir.glob按模式pattern搜索文件系统里的文件和目录名并通过关键字参数控制搜索起点base、匹配行为flags和结果数组的排序sort。Ruby 仓库自带的文档 filename globbing 说明 完整覆盖了这三点本文的命令与输出均取自该文档示例输出是在 Ruby 源码目录中运行得到的具体文件清单随目录内容变化。先分清三个 glob 方法与它们的返回值Ruby 中承担文件名 glob 的方法有三个注意它们在flags支持上的差异方法返回值是否支持flags关键字Dir.glob无块匹配到的字符串数组支持Dir.glob带块对每个匹配项调用块返回nil支持Dir[]匹配到的字符串数组不支持其 flags 值固定为 0Pathname#glob无块Pathname对象数组支持Pathname#glob带块对每个Pathname调用块支持文档中的基础用法示例文档示例输出对应 Ruby 源码目录的内容Dir[*].take(3) # [BSDL, CONTRIBUTING.md, COPYING] Dir.glob(*).take(3) # [BSDL, CONTRIBUTING.md, COPYING] Dir.glob(*.rb) {|entry_name| puts entry_name } # nil Pathname(.).glob(*).take(3) # [#Pathname:BSDL, #Pathname:CONTRIBUTING.md, #Pathname:COPYING]带块形式适合边遍历边处理而不保留整个数组比如只收集.c文件a [] Pathname(.).glob(*) {|pn| a pn if pn.to_s.end_with?(.c) } # nil a.take(3) # [#Pathname:addr2line.c, #Pathname:array.c, #Pathname:ast.c]模式元素的写法与默认行为patterns 参数是字符串或字符串数组不是 Regexp。各模式元素及其含义模式含义示例普通字符串匹配自身LEGAL*匹配任意长度字符序列*.txt?匹配任意单个字符?.txt[abc]、[^abc]匹配集合中的单个字符^表示取反x[abc]y[a-z]、[^a-z]匹配区间中的单个字符x[0-9]y{ , }匹配多个备选之一{abc,def}**递归匹配目录需紧跟/**/test.rb\转义下一个字符\\*、\?写模式时要牢记几条默认行为文档均在 Ruby 源码目录验证过大小写敏感且不能通过 flags 改变。Dir.glob(LEGAL)返回[LEGAL]而Dir.glob(legal)返回[]Dir.glob(LEGA)也返回[]必须精确匹配。*和?默认不匹配以点开头的文件Dir.glob(*).select {|entry| entry.start_with?(.) } # []*不跨越路径分隔符所以Dir.glob(*.rb)的结果中不含/Dir.glob(*.rb).select {|entry| entry.include?(/) } # []字符集合与区间Dir.glob([efgh][abcd])返回[gc]取反写法Dir.glob([^abcd][^efgh])同样返回[gc]。区间写法示例Dir.glob([k-m][h-j][a-c]) # [lib]。备选模式{ , }中空格有意义Dir.glob({k ,L,R}*)会把k带空格当作独立选项处理返回[LEGAL, README.ja.md, README.md]文档示例。转义反斜杠可转义 glob 特殊字符Dir.glob(\*)与Dir.glob(\**/*.rb)都返回[]因为目录里没有名为*的条目。Windows 注意反斜杠在 Windows 上同样是转义符不能用作路径分隔符Dir.glob(C:\Users\*)匹配不到任何文件应写成Dir.glob(C:/Users/*)。外部来源如环境变量的路径可先转换pattern path.tr(\\, /)。用**递归搜索子目录**只有紧跟/时才递归匹配目录否则等价于*文档验证Dir.glob(**) Dir.glob(*)为true。在 Ruby 源码目录中递归搜索的文档示例# 找到所有以 .ja 结尾的条目 Dir.glob(**/*.ja) # [COPYING.ja, doc/pty/README.expect.ja, doc/pty/README.ja] # 只在 lib 目录下递归找 .rb Dir.glob(lib/**/*.rb).take(3) # [lib/English.rb, lib/bundled_gems.rb, lib/bundler/build_metadata.rb]以/结尾的模式只匹配目录名且匹配到的名称自带结尾/Dir.glob(*/).take(3) # [basictest/, benchmark/, bin/] Dir.glob(**/).take(3) # [basictest/, benchmark/, benchmark/gc/]用base指定搜索起点base指定搜索从哪个目录开始默认.对Pathname#glob该参数被忽略起点就是Pathname对象自身的字符串路径。注意结果中的条目名不会带上 base 目录前缀。文档示例Dir.glob(*).take(3) # 默认 base . # [BSDL, CONTRIBUTING.md, COPYING] Dir.glob(*, base: lib).take(3) # [English.gemspec, English.rb, bundled_gems.rb] Dir.glob(*, base: lib/net).take(3) # [http, http.rb, https.rb] Pathname(lib/net).glob(*).take(3) # [#Pathname:lib/net/http, #Pathname:lib/net/http.rb, #Pathname:lib/net/https.rb]用flags修改匹配行为flags默认0可取File::FNM*常量的按位或Dir.glob(*, flags: File::FNM_DOTMATCH | File::FNM_NOESCAPE)glob 实际生效的常量只有三个常量作用File::FNM_DOTMATCH让*匹配以点开头的条目File::FNM_NOESCAPE关闭转义File::FNM_SHORTNAME启用 Windows 短文件名8.3 名匹配仅 Windows 有效File::FNM_CASEFOLD、File::FNM_EXTGLOB、File::FNM_PATHNAME、File::FNM_SYSCASE这四个常量不影响文件名 glob。File::FNM_DOTMATCH让*匹配隐藏条目默认不匹配 dotfile加上该 flag 后匹配下面计数是文档在 Ruby 源码目录得到的示例值你的目录会得到不同的数Dir.glob(*).size # 241 Dir.glob(*, flags: File::FNM_DOTMATCH).size # 256 Dir.glob(*, flags: File::FNM_DOTMATCH).take(3) # [., .dir-locals.el, .document]在任意目录验证该 flag 是否生效只需对比两次.size带File::FNM_DOTMATCH的次数值应不小于不带 flag 的次。File::FNM_NOESCAPE关闭转义Dir.glob(\*).size # 0 Dir.glob(\*, File::FNM_NOESCAPE).size # 0文档同时指出在 Windows 上该 flag 不会让反斜杠变成路径分隔符——反斜杠只是按普通字符匹配而条目名中不可能出现它。File::FNM_SHORTNAMEWindows 短文件名默认禁用加上该常量后模式可匹配 Windows 短文件名8.3 文件名用于与依赖短文件名的旧应用保持兼容。用sort控制结果是否排序sort默认true结果按名称排序传sort: false则按目录返回的自然顺序输出。文档示例未排序的前三个条目顺序不固定是目录序Dir.glob(*).take(3) # [BSDL, CONTRIBUTING.md, COPYING] Dir.glob(*, sort: false).take(3) # [gc.rb, yjit.rb, iseq.h]Pathname#glob同样支持Pathname(.).glob(*, sort: false).take(3)得到[#Pathname:gc.rb, #Pathname:yjit.rb, #Pathname:iseq.h]。如果后续逻辑依赖稳定的处理顺序例如逐个写入日志应保留默认排序或自行排序不要依赖sort: false的目录序。验证清单与边界在一个目录中按下表逐项确认行为均可直接执行输出条目名随目录内容不同而变化判断依据是规则而非具体名称Dir.glob(**) Dir.glob(*) # 应为 true** 未跟 / 时等价于 * Dir.glob(*).select {|e| e.start_with?(.) }.size # 默认应为 0 Dir.glob(*, flags: File::FNM_DOTMATCH) .size Dir.glob(*).size # 加 flag 后条目数不减 Dir.glob(*).sort Dir.glob(*) # 默认返回已排序 Dir.glob(*, sort: false).sort Dir.glob(*) # 两种结果集合相同仅顺序不同边界与限制Dir[]不接受flags关键字参数需要 flags 时改用Dir.glob。大小写敏感性没有任何 flag 可以修改。Dir.glob访问真实文件系统对字符串做模式匹配不访问文件系统的是另一套 filename matching 方法File.fnmatch等文档见 filename matching两者不要混用。文档中**/*.rb的条目计数如 7527是 Ruby 源码树特定状态下的示例值仅用于说明量级不应作为固定预期。完整规则与更多示例见 doc/file/filename_globbing.md。【免费下载链接】rubyThe Ruby Programming Language项目地址: https://gitcode.com/GitHub_Trending/ru/ruby创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价