Node glob语法

原文地址:github.com/isLishude/b…javascript

本文Ivan Yan 翻译,"署名-非商用-相同方式共享",意见反馈java

经过星号等 shell 所用的模式匹配文件。node

这是一个 JavaScript 版本的 glob 实现。使用 minimatch 执行匹配操做。git

译注:早期 Unix (第 1-6 版,1969-1975)的命令行解释器依赖独立程序 /etc/glob 展开参数中的通配符。这个程序会展开通配符并把展开后的文件列表传给命令。它的名字是 "global command" 的简称。后来这个功能由工具函数 glob() 提供,被 shell 等程序使用。(译自 WikiPedia。)github

用法

用 npm 安装:正则表达式

npm i glob
复制代码
var glob = require("glob")

// options 可选
glob("**/*.js", options, function (er, files) {
  // files 是一个文件名数组。
  // 若是设置了选项 `nonull` 而且没有找到匹配,则 files 是 ["**/*.js"]
  // er 是一个错误对象或 null。
})
复制代码

Glob 基础

"Globs" 是像这样的模式:用在命令行中的 ls *.js, 用在 .gitignore 文件中的 build/*shell

在解析路径中的模式前,先展开大括号部分。大括号部分以 { 开始,以 } 结束,里面是一个逗号分隔列表。大括号部分能够包含斜杠,例如 a{/b/c,bcd} 将展开为 a/b/cabcdnpm

译注:好比路径 "/foo/bar", 其中 "foo" 与 "bar" 是路径片断(path portion)。数组

下面这些字符在路径片断中有特别的意义:缓存

  • * 匹配路径片断中零个或多个字符。
  • ? 匹配一个字符。
  • [...] 匹配一个字符集合,相似于正则表达式的字符集合。若是第一个字符是 !^ 那么它匹配一个不在这个字符集合内的字符。
  • !(pattern|pattern|pattern) 匹配不匹配模式的文件。
  • ?(pattern|pattern|pattern) 匹配这些模式零次或一次。
  • +(pattern|pattern|pattern) 匹配这些模式一次或屡次。
  • *(a|b|c) 匹配这些模式零次或屡次。
  • @(pattern|pat*|pat?erN) 匹配这些模式一次。
  • ** 即 globstar 模式,若是这是单独的一个路径片段,则匹配零级或多级目录,但不会搜索符号连接目录。

点号

若是文件或目录路径片断的第一个字符是点号(.),那么它将不匹配任何 glob,除非 glob 相应的路径片断的第一个字符也是 .

例如,a/.*/c 匹配 a/.b/c,可是 a/*/c 不匹配,由于 * 第一个字符不是 .

能够设置选项 dot:true,将 . 看成普通的字符。

译注:点文件(dot file),名字以 . 开始,在 Unix 下是隐藏文件。即便使用 globstar 模式,a/**/c 也不会匹配 a/.b/c

匹配基本名

若是设置选项 matchBase:true,而且模式不包含斜杠,那么将搜索目录树下任意地方的匹配基本名(basename)的文件。例如 *.js 匹配 test/simple/basic.js

空集

若是没有找到匹配的文件,那么返回一个空的数组。这跟 shell 不一样,shell 会返回模式。例如:

$ echo a*s*d*f
a*s*d*f
复制代码

想与 shell 一致,设置选项 nonull:true

其它参考

  • man sh
  • man bash (搜索 "Pattern Matching")
  • man 3 fnmatch
  • man 5 gitignore
  • minimatch 文档

glob.hasMagic(pattern, [options])

若是模式包含特殊的字符则返回 true,不然返回 false

注意选项会影响结果。若是设置了选项 noext:true,则 +(a|b) 不会视为魔法模式。若是模式包含大括号展开式,好比 a/{b/c,x/y},则认为是魔法的,除非设置了选项 nobrace:true

glob(pattern, [options], cb)

  • pattern {String} 待匹配的模式
  • options {Object}
  • cb {Function}
    • err {Error | null}
    • matches {Array<String>} 匹配模式的文件名

进行一个异步的 glob 搜索。

glob.sync(pattern, [options])

  • pattern {String} 待匹配的模式
  • options {Object}
  • return: {Array<String>} 匹配模式的文件名

进行一个同步的 glob 搜索。

Class: glob.Glob

实例化 glob.Glob 类,建立一个 Glob 对象。

var Glob = require("glob").Glob
var mg = new Glob(pattern, options, cb)
复制代码

这是一个 EventEmitter 对象,马上开始遍历文件系统搜索匹配。

new glob.Glob(pattern, [options], [cb])

  • pattern {String} 待匹配的模式

  • options {Object}

  • cb {Function}

    当遇到错误或找到匹配时调用

    • err {Error | null}
    • matches {Array<String>} 匹配模式的文件名

注意,若是设置了选项 sync,则匹配将当即添加到 g.found

属性

  • minimatch glob 所用的 minimatch 对象。
  • options 传入的选项。
  • aborted 布尔值,当调用 abort() 时设为 true。取消以后不能继续 glob 搜索,不过能够经过重用 statCache 避免重复调用 syscall。
  • cache 缓存。每一个字段均可以取下面的值:
    • false - 路径不存在
    • true - 路径存在
    • 'FILE' - 路径存在,而且不是目录
    • 'DIR' - 路径存在,而且是目录
    • [file, entries, ...] - 路径存在, 而且是目录,数组值是 fs.readdir 的结果
  • statCache 缓存 fs.stat 的结果,阻止屡次读取同一路径的信息。
  • symlinks 记录哪些路径是符号连接,与 ** 解析相关。
  • realpathCache 可选对象,传给 fs.realpath,以减小没必要要的 syscall。它保存在 Glob 实例上,能够重用。

事件

  • end 当结束搜索匹配时触发此事件,包含全部的匹配。若是设置了选项 nonull,而且没有找到匹配,则 matches 包含原来的模式。匹配通过排序,除非设置了选项 nosort
  • match 每当找到一个匹配时以这个匹配触发此事件,匹配没有去重,也没有解析为真实路径。
  • error 当遇到一个异常时, 或者在设置了 options.strict 的状况下遇到 fs 错误时触发此事件。
  • abort 当调用 abort() 时触发此事件。

方法

  • pause 暂停搜索。
  • resume 继续搜索。
  • abort 取消搜索。

选项

全部能够传给 Minimatch 的选项也能够传给 Glob,选项会改变匹配行为。有些选项是新加的,有些选项是 glob 特定选项。

全部选项默认是 false, 除非特别说明。

全部选项也会添加给 Glob 对象。

若是运行多个 glob 操做,能够将一个 Glob 对象做为 options 参数传递给后面的操做,以简化一些 statreaddir 的调用。在最新的版本里,你能够传入共享的 symlinks, statCache, realpathCache, cache 选项,这样并行的 glob 操做将由于共享文件系统的信息而提速。

  • cwd String,搜索的工做目录,默认为 process.cwd()
  • root String,以 / 开始的模式的挂载目录,默认为 path.resolve(options.cwd, "/") (Unix 系统下为 /,Windows 系统下为 C:\ 或其它磁盘根目录。)
  • dot 在常规匹配与 globstar 匹配中包含点文件。注意,. 在模式片段中始终匹配点文件。
  • nomount/ 开始的模式默认挂载到 root 选项设置的目录上,于是返回一个合法的文件系统路径。设置此选项禁止此行为。
  • mark 给匹配的目录添加一个 / 字符。注意这会调用 stat
  • nosort 不排序结果。
  • stat stat 全部的结果。这多少会下降性能,彻底不必,除非认为 readdir 不能做为文件存在的可靠指示。
  • silent 当读取目录时遇到一个不常见的错误,将打印一条警告到 stderr。设置此选项可取消打印。
  • strict 当读取目录时遇到一个不常见的错误,进程将继续搜索其它匹配。设置此选项可抛出错误。
  • cache Object, 见上文。传入以前生成的缓存对象能够节省一些 fs 调用。
  • statCache Object, 匹配结果的文件系统信息的缓存,用来阻止没必要要的 stat 调用。一般不须要设置此选项。不过若是知道文件系统在不一样的 glob() 调用之间不会变化,能够将一个 glob() 调用的 statCache 传给另外一个调用的选项(见下面“竞态条件”)。
  • symlinks Object, 已知的符号连接的缓存。能够传入一个以前生成的 symlinks 对象,在匹配 ** 时节省 lstat 调用。
  • sync 废弃,能够用 glob.sync(pattern, opts)
  • nounique 在有些状况下,大括号展开式会致使在结果里面同一文件出现屡次。本实现默认阻止结果里面出现重复。此选项禁止此行为。
  • nonull 不返回空集,返回一个包含模式的集合,这是 glob(3) 的默认行为。
  • debug 启用 minimatch 和 glob 调试。
  • nobrace 不展开 {a,b}{1..3} 这样的集合。
  • noglobstar 不支持 "globstar" 模式,这时 ** 不匹配多级文件名,像普通的 * 同样对待。
  • noext 不支持 "extglob" 模式,好比 +(a|b)
  • nocase 匹配不区分大小写。注意:在不区分大小写的系统里,默认匹配没有特殊字符的模式,由于 statreaddir 不会抛出异常。
  • matchBase 若是模式不包含斜杠则匹配基名字。例如 *.js 将视为 **/*.js,匹配全部目录下的 js 文件。
  • nodir 不匹配目录,只匹配文件。注意若是只匹配目录,简单地在模式的末尾放一个 / 便可。
  • ignore 添加一个模式或一个 glob 模式数组,用来排除匹配。注意:ignore 模式始终认为 dot:true,无论其它的配置是怎样的。
  • follow 在展开 ** 时追踪符号连接目录。注意这可能致使大量重复的引用(循环连接)。
  • realpath 在全部的结果上调用 fs.realpath,在不能解析符号连接的状况下,返回匹配文件的全路径,不过它经常是一个损坏的符号连接。
  • absolute 设为 true 时始终获得匹配文件的绝对地址。不一样于 realpath,这同时影响 match 事件的返回值。

与其它 fnmatch/glob 实现的比较

严格地兼容现实规范是值得追求的目标,不过 node-glob 与其它实现之间存在差别,而且是有意的。

默认支持 **,除非设置了选项 noglobstar。这也是 bsdglob 和 bash 4.3 的方式。只有当 ** 是单独的一个路径片断时它才有这种特殊意义。例如 a/**/b 匹配 a/x/y/b,可是 a/**b 不会。

注意,** 不会搜索符号连接目录,尽管它们可能匹配模式的其它片段。这能够防止无限循环、重复等。

若是转义的模式没有找到匹配,而且设置了选项 nonull,则 glob 原样返回模式,而不是转义后的模式。例如 glob.match([], "\\*a\\?") 返回 "\\*a\\?" 而不是 "*a?"。默认的行为相似于在 bash 里设置 nullglob 选项,除了 bash 不会解析转义的模式。

若是没有禁止展开大括号,则在解析 glob 的其它模式以前先展开它。例如 +(a|{b),c)},在 bash 或 zsh 下面是无效的,在这儿会先展开为 +(a|b)+(a|c),再检查这两个模式的有效性。既然它们是有效的,则进行匹配。

注释与排除

在以前的版本中,若是模式以 # 开始则它是一个注释。标记为注释。若是模式以 ! 开始则它是一个排除模式。

v5 已经废弃了选项 nonegatenocomment。v6 则删除了这两个选项。

若是想排除某些文件,可使用选项 ignore

Windows

请在 glob 表达式里只使用斜杠。

译注:斜杠(forward-slashe "/")是顺时针方向,反斜杠(backward-slashe "")是逆时针方向。

尽管 Windows 能够用 /\ 做为路径分隔符,可是本实现只使用 /。在 glob 表达式里必须只使用斜杠。反斜杠始终视为转义符,而不是路径分隔符。

绝对路径模式好比 /foo/*,匹配结果挂载到选项 root 设置的目录上(使用 path.join())。 在 Windows 下,在默认的状况下,/foo/* 能够匹配到 C:\foo\bar.txt(译注:此时 cwd 在 C 盘下)。

竞态条件

Glob 搜索本质上容易受竞态条件(race conditions)的影响,由于它创建在目录遍历等上面。

所以,当 glob 搜索某个文件时它是存在的,而后在返回结果时它可能被删除或被修改。

做为内部实现的一部分,为了下降系统开销,此实现缓存了全部的 stat 和 readdir 的结果。可是,这也致使它更加容易受竞态条件的影响,特别是在多个 glob 调用之间重用 cache 或 statCache 对象时。

在面对快速的变化时,建议用户不要将 glob 结果做为文件系统状态的担保。对于绝大多数的操做,这毫不会是一个问题。

贡献

对程序行为的任何改变(包含补丁)必须同时提交测试。

测试失败的或下降性能的补丁将被拒绝。

# to run tests
npm test

# to re-generate test fixtures
npm run test-regen

# to benchmark against bash/zsh
npm run bench

# to profile javascript
npm run prof
复制代码

关注公众号,发现更多精彩

相关文章
相关标签/搜索