如何编写一个匹配所有不在目录中的 js 文件的最小匹配 glob
How to write a single minimatch glob that matches all js files not in a directory
我遇到这样一种情况,我需要一个单一的 glob 模式(使用 minimatch
)来匹配不在特定目录中的所有 JavaScript 文件。不幸的是,我正在使用另一个不公开任何选项的工具(如 ignore
glob),因此它必须是一个单一的 glob 才能完成这项工作。
示例输入(应该不匹配顶部,但应该匹配底部):
docs/foo/thing.js
docs/thing.js
client/docs/foo/thing.js
client/docs/thing.js
src/foo/thing.js
src/thing.js
docs-src/foo/thing.js
docs-src/thing.js
client/docs-src/foo/thing.js
client/docs-src/thing.js
到目前为止,这是我对 glob 模式的了解:
**/!(docs)/*.js
因此我匹配 docs/foo/thing.js
和 client/docs/foo/thing.js
而不是匹配 docs-src/thing.js
或 client/docs-src/thing.js
。如果我将 glob 切换为 **/!(docs)/**/*.js
,那么我可以匹配 client/docs-src/thing.js
,但我也会匹配 client/docs/thing.js
.
我不确定这是否可行,所以我可能需要为我的问题找到另一种解决方案:-/
我认为您可能 运行 受 minimatch(或 fnmatch(3) 的任何实现)和 globstar 的限制。也许值得注意的是,我所知道的 fnmatch 的 C 实现实际上 确实 实现了 globstar,但是由于 fnmatch impls(包括 minimatch)服务于他们的 globbers 的利益,这可能会有所不同。
当用作 glob 时,您认为应该起作用的 glob 实际上确实起作用。
$ find . -type f
./docs/foo/thing.js
./docs/thing.js
./docs/nope.txt
./docs-src/foo/thing.js
./docs-src/thing.js
./x.sh
./client/docs/foo/thing.js
./client/docs/thing.js
./client/docs/nope.txt
./client/docs-src/foo/thing.js
./client/docs-src/thing.js
./client/docs-src/nope.txt
./client/nope.txt
./src/foo/thing.js
./src/thing.js
$ for i in ./!(docs)/**/*.js; do echo $i; done
./client/docs-src/foo/thing.js
./client/docs-src/thing.js
./client/docs/foo/thing.js
./client/docs/thing.js
./docs-src/foo/thing.js
./docs-src/thing.js
./src/foo/thing.js
./src/thing.js
$ node -p 'require("glob").sync("./!(docs)/**/*.js")'
[ './client/docs-src/foo/thing.js',
'./client/docs-src/thing.js',
'./client/docs/foo/thing.js',
'./client/docs/thing.js',
'./docs-src/foo/thing.js',
'./docs-src/thing.js',
'./src/foo/thing.js',
'./src/thing.js' ]
编辑:哦,我明白了,你只想匹配任何文件夹深度没有 any docs
路径部分 anywhere 的东西 在路径中。不,这是不可能以支持任意深度的方式做到的,如 glob 或最小匹配模式。您必须使用排除,或构造一个看起来像这样的 glob:{!(docs),!(docs)/!(docs),!(docs)/!(docs)/!(docs),!(docs)/!(docs)/!(docs)/!(docs)}/*.js
否则,像 x/docs/y/z.js
这样的路径将匹配 **/!(docs)/**/*.js
,即第一个 **
不匹配,!(docs)
匹配 x
,接下来的 **
匹配 docs/y
然后 *.js
匹配 z.js
.
我靠得更近了,有以下几点:
**/?(docs*[a-zA-Z0-9]|!(docs))/*.js
仍在努力使其适用于任意深度。
我遇到这样一种情况,我需要一个单一的 glob 模式(使用 minimatch
)来匹配不在特定目录中的所有 JavaScript 文件。不幸的是,我正在使用另一个不公开任何选项的工具(如 ignore
glob),因此它必须是一个单一的 glob 才能完成这项工作。
示例输入(应该不匹配顶部,但应该匹配底部):
docs/foo/thing.js
docs/thing.js
client/docs/foo/thing.js
client/docs/thing.js
src/foo/thing.js
src/thing.js
docs-src/foo/thing.js
docs-src/thing.js
client/docs-src/foo/thing.js
client/docs-src/thing.js
到目前为止,这是我对 glob 模式的了解:
**/!(docs)/*.js
因此我匹配 docs/foo/thing.js
和 client/docs/foo/thing.js
而不是匹配 docs-src/thing.js
或 client/docs-src/thing.js
。如果我将 glob 切换为 **/!(docs)/**/*.js
,那么我可以匹配 client/docs-src/thing.js
,但我也会匹配 client/docs/thing.js
.
我不确定这是否可行,所以我可能需要为我的问题找到另一种解决方案:-/
我认为您可能 运行 受 minimatch(或 fnmatch(3) 的任何实现)和 globstar 的限制。也许值得注意的是,我所知道的 fnmatch 的 C 实现实际上 确实 实现了 globstar,但是由于 fnmatch impls(包括 minimatch)服务于他们的 globbers 的利益,这可能会有所不同。
当用作 glob 时,您认为应该起作用的 glob 实际上确实起作用。
$ find . -type f
./docs/foo/thing.js
./docs/thing.js
./docs/nope.txt
./docs-src/foo/thing.js
./docs-src/thing.js
./x.sh
./client/docs/foo/thing.js
./client/docs/thing.js
./client/docs/nope.txt
./client/docs-src/foo/thing.js
./client/docs-src/thing.js
./client/docs-src/nope.txt
./client/nope.txt
./src/foo/thing.js
./src/thing.js
$ for i in ./!(docs)/**/*.js; do echo $i; done
./client/docs-src/foo/thing.js
./client/docs-src/thing.js
./client/docs/foo/thing.js
./client/docs/thing.js
./docs-src/foo/thing.js
./docs-src/thing.js
./src/foo/thing.js
./src/thing.js
$ node -p 'require("glob").sync("./!(docs)/**/*.js")'
[ './client/docs-src/foo/thing.js',
'./client/docs-src/thing.js',
'./client/docs/foo/thing.js',
'./client/docs/thing.js',
'./docs-src/foo/thing.js',
'./docs-src/thing.js',
'./src/foo/thing.js',
'./src/thing.js' ]
编辑:哦,我明白了,你只想匹配任何文件夹深度没有 any docs
路径部分 anywhere 的东西 在路径中。不,这是不可能以支持任意深度的方式做到的,如 glob 或最小匹配模式。您必须使用排除,或构造一个看起来像这样的 glob:{!(docs),!(docs)/!(docs),!(docs)/!(docs)/!(docs),!(docs)/!(docs)/!(docs)/!(docs)}/*.js
否则,像 x/docs/y/z.js
这样的路径将匹配 **/!(docs)/**/*.js
,即第一个 **
不匹配,!(docs)
匹配 x
,接下来的 **
匹配 docs/y
然后 *.js
匹配 z.js
.
我靠得更近了,有以下几点:
**/?(docs*[a-zA-Z0-9]|!(docs))/*.js
仍在努力使其适用于任意深度。