glob 模式通配符

glob 命令是 global 的缩写,起源于贝尔实验室最早的 Unix 版本,最初是用 B 编程语言编写的,后来,此功能作为 C 库函数提供给 Shell 等程序使用。

在计算机编程中,glob 模式通配符用于指定文件名集。

例如,Unix Bash shell 命令:

# 将所有名称以 .txt 结尾的文件,从当前目录移动到 dir 目录
mv *.txt dir/

# 将所有以单个字符命名、以 .txt 结尾的文件,从当前目录移动到 dir 目录
mv ?.txt dir/

这里,* 是一个通配符,表示除 / 之外的任何字符串? 也是一个通配符,表示一个字符,同理,?? 表示两个字符。

除了匹配文件名之外,glob 还广泛用于匹配任意字符串(通配符匹配)。

传统上,glob 不匹配 Unix 点文件形式的隐藏文件;为了匹配它们,模式必须明确地以 . 开始。例如,* 匹配所有可见文件,.* 匹配所有隐藏文件。

特殊符号

glob 是由普通字符、/(斜杠)和通配符(也称元字符)组成的字符串,用于匹配文件路径。glob 本身属于一种标准,并且各类语言都有其完整实现。POSIX 基础 glob 主要是 *?[]**{}()(extglob)以及单独的 !pattern 属于扩展,Bash、minimatch 等支持,具体以实现为准。

glob 语法中的特殊符号如下:

  • 基础语法:/*?[][!] 在括号内表示取反)
  • 拓展语法:**{}()、单独的 !

/(分隔符)

/ 用于将一个字符串分隔为多个字符串片段,通过 split('/') 得到的数组每一项是一个字符串片段。也就是说,字符串片段就是两个分隔符之间的所有字符组成的字符串。

在 glob 中,分隔符永远是 / 字符。不区分操作系统,即使是在采用 \ 作为分隔符的 Windows 操作系统中。

# src 目录下的 a.js
src/a.js
  • src/index.js:有两个片段,即 srcindex.js
  • src/**/*.js:有三个片段,即是 src***.js

注意: 在 glob 中,\\ 字符被保留作为转义符使用。

*(星号)

* 用于匹配一个字符串片段中任意数量的字符,包括零个字符。

  • src/*.js:匹配 src 目录下所有以 .js 结尾的文件,但不能匹配 src 子目录中的文件,如 src/js/a.js 等。
  • src/**/*.js:匹配 src 目录及其子目录下所有以 .js 结尾的文件,如 src/js/a.jssrc/js/dir/a.js 等。

?(问号)

? 用于匹配单个片段中的单个字符。

  • src/?.js:匹配 src 目录下的 src/a.jssrc/b.js 等,但不能匹配 src/ab.jssrc/dir/a.js 等。
  • src/index.??:匹配 src 目录下以 index 开头、后缀名是两个字符的文件,例如 src/index.jssrc/index.md,但不能匹配 src/index.jsx

!(惊叹号)

[] 里,[!abc] 表示「不是这些字符」,这是 POSIX 写法。单独写在模式最前面的 ! 表示取反(排除后面能匹配到的路径),这是 minimatch、gitignore 等扩展,不是 POSIX glob。

  • src/[!ab].js:匹配 src/c.jssrc/d.js 等,不能匹配 src/a.jssrc/b.js 等。
  • !src/temp/**:排除 src/temp 目录下的所有目录和文件。

[](中括号)

[] 用于匹配单个字符串片段中的单个字符,但是字符集只能从括号内选择,如果字符集内有 -,表示范围。

  • src/[ab].js:只能匹配 src/a.jssrc/b.js
  • src/[!ab].js:不能匹配 src/a.jssrc/b.js
  • src/[c-z].js:匹配 src/c.jssrc/d.js、...、src/z.js,但不能匹配 src/a.jssrc/b.js

**(双星号)

** 必须单独占一个路径片段时,才在多个字符串片段中匹配任意数量的目录,包括零个。也就是说,递归匹配所有文件和目录(默认不含隐藏的文件和目录)。写成 **.js 时,多数实现会把它当成普通的 *不会跨目录。

  • src/js/**:匹配 src/js 目录下所有文件和文件夹,以及所有子文件和子文件夹。
  • src/js/**/*.js:匹配 src/js 目录及其子目录下的所有以 .js 结尾的文件。

()(圆括号)

() 必须跟在 ?*+@! 后面使用(Bash extglob / minimatch),且圆括号里面的内容是一组以 | 分隔的 glob 模式集合。

  • ?(pattern|pattern|pattern):匹配 0 次或 1 次给定的模式。
  • *(pattern|pattern|pattern):匹配任意次数给定的模式。
  • +(pattern|pattern|pattern):匹配 1 次或多次给定的模式。
  • @(pattern|pattern|pattern):恰好匹配其中一种给定的模式。
  • !(pattern|pattern|pattern):排除给定的模式。

{}(大括号)

{} 用于匹配指定的多个 glob 模式(花括号展开,发生在 glob 匹配之前),模式之间用逗号进行分隔,支持大括号嵌套,支持用 .. 匹配连续的字符,即 {start..end} 语法。

  • {ab,cd/ef}/*.js:匹配 ab/file.jscd/ef/file.js
  • a.{png,jp{,e}g}:匹配 a.pnga.jpga.jpeg
  • {a..c}{1..2}:匹配 a1a2b1b2c1c2

glob 与 RegExp 的区别

在编程中匹配字符最常见的工具是正则表达式(RegExp),而 glob 模式除了用于匹配文件路径,也可以用于匹配字符串。

glob 在 RegExp 出现之前就有了,它在某些方面与 RegExp 功能相同,但是功能不如 RegExp 强大,且两者也有着不同的语法和约定。

符号 Glob RegExp
* 0 或多个任意字符 量词,匹配规则的 0 或多个字符
? 任意单个字符 量词,匹配规则的 0 或 1 个字符
. 非特殊字符 任意单个字符
{} 匹配组 量词,匹配次数
Glob Regexp 精确的 Regexp
* .* /^(?:(?!.)(?=.)/*?)$/
? . /^(?:(?!.)(?=.)/)$/

备注: glob 匹配的是整个字符串,而 Regexp 默认匹配的是子串,Regexp 如果要匹配整个字符串需显式指定 ^$

在 JavaScript 中,正则表达式是以标准 API 形式提供的,开箱即用。但是 glob 模式匹配并非 JavaScript 中的标准 API,需要自行解析和匹配。

minimatch 是 npm 内部使用的匹配库,支持 glob 基础语法和扩展语法,还可以实现 glob 的测试、匹配以及转换成正则表达式。

const { minimatch } = require("minimatch")
// 较新版本:import { minimatch } from "minimatch"

minimatch("src/a.js", "src/*.js") // true
minimatch("src/b.js", "src/*.js") // true
minimatch("src/dir/a.js", "src/*.js") // false

minimatch.makeRe('*') // /^(?:(?!\.)(?=.)[^/]*?)$/
minimatch.makeRe('?') // /^(?:(?!\.)(?=.)[^/])$/

旧版 minimatch 也可直接 const minimatch = require("minimatch") 得到函数本身。

使用场合

  • Node.js:npm 的 glob 包;Node.js 22 起可用内置 fs.glob / fs.promises.glob
  • Git 的 .gitignore 文件(规则类似 glob,但不完全相同,例如目录尾斜杠、! 表示取消忽略)。
  • TypeScript 的 tsconfig.jsonincludeexclude 等配置项。

参考资料

glob (programming) - 维基)

© lizhao all right reserved,powered by Gitbook文件修订时间: 2026-09-02 22:45:15

results matching ""

    No results matching ""