如何编写一个单一的 minimatch glob,以匹配不在某个目录中的所有 js 文件

5
我面临这样一种情况,需要使用单个glob模式(使用minimatch)来匹配所有不在特定目录中的JavaScript文件。不幸的是,我使用的另一个工具没有暴露任何选项(如ignore glob),因此必须使用单个glob来完成任务。 这是我目前拥有的内容

screenshot of globtester

示例输入(它不应该匹配顶部,但它应该匹配底部):

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

以下是我对全局模式的现有内容:

**/!(docs)/*.js

我正在匹配 docs/foo/thing.jsclient/docs/foo/thing.js,而不是匹配 docs-src/thing.jsclient/docs-src/thing.js。如果我将我的glob切换为** /!(docs)/**/*.js,那么我可以匹配client/docs-src/thing.js,但我也会匹配client/docs/thing.js

我不确定这是否可能,所以我可能需要找到另一个解决方案来解决我的问题 :-/

2个回答

5

我认为你可能遇到了minimatch(或fnmatch(3)的任何实现)和globstar的限制。值得注意的是,据我所知,没有一个C实现的fnmatch实际上实现了globstar,但由于fnmatch实现(包括minimatch)服务于它们的globbers的利益,这可能会有所不同。

当作为全局通配符使用时,你认为应该起作用的通配符确实起作用。

$ 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' ]

编辑:哦,我明白了,您只想匹配在路径中任何文件夹深度下都没有 任何 docs 路径部分的内容。对于支持任意深度的 glob 或 minimatch 模式来说,这是不可能的。您必须使用排除或构建一个类似于以下形式的 glob:{!(docs),!(docs)/!(docs),!(docs)/!(docs)/!(docs),!(docs)/!(docs)/!(docs)/!(docs)}/*.js

否则,像 x/docs/y/z.js 这样的路径将通过说第一个 ** 匹配不到任何内容,!(docs) 匹配 x,下一个 ** 匹配 docs / y,然后 *.js 匹配 z.js


"这不可能"是一个可以接受的答案。我会想出其他办法的。谢谢Isaacs! - kentcdodds
我想知道为什么包含(?)可以在任意深度下正常工作,而排除(!)却不能。 - Apidcloud

1
我更接近了,以下是:

**/?(docs*[a-zA-Z0-9]|!(docs))/*.js

globtester

仍在尝试使它适用于任意深度。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接