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
複製代碼

關注公衆號,發現更多精彩

相關文章
相關標籤/搜索