admin管理员组

文章数量:1404583

I have a situation where I need a single glob pattern (that uses minimatch) to match all JavaScript files which are not in a certain directory. Unfortunately, I'm using another tool that doesn't expose any options (like an ignore glob), so it has to be a single glob to do the job.

Here's what I have so far

Example input (it should not match the top, but it should match the bottom):

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

And here's what I have for the glob pattern so far:

**/!(docs)/*.js

With that I'm matching docs/foo/thing.js and client/docs/foo/thing.js and not matching docs-src/thing.js or client/docs-src/thing.js. If I switch my glob to **/!(docs)/**/*.js then I can match client/docs-src/thing.js, but I also match client/docs/thing.js.

I'm not certain this is possible so I may need to find another solution for my problem :-/

I have a situation where I need a single glob pattern (that uses minimatch) to match all JavaScript files which are not in a certain directory. Unfortunately, I'm using another tool that doesn't expose any options (like an ignore glob), so it has to be a single glob to do the job.

Here's what I have so far

Example input (it should not match the top, but it should match the bottom):

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

And here's what I have for the glob pattern so far:

**/!(docs)/*.js

With that I'm matching docs/foo/thing.js and client/docs/foo/thing.js and not matching docs-src/thing.js or client/docs-src/thing.js. If I switch my glob to **/!(docs)/**/*.js then I can match client/docs-src/thing.js, but I also match client/docs/thing.js.

I'm not certain this is possible so I may need to find another solution for my problem :-/

Share Improve this question asked Jan 19, 2018 at 21:42 kentcdoddskentcdodds 29.1k33 gold badges111 silver badges192 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

I think you may be running into a limitation of minimatch (or any implementation of fnmatch(3)) and globstar. It's perhaps worth noting that no C implementation of fnmatch that I'm aware of actually does implement globstar, but since fnmatch impls (including minimatch) serve the interests of their globbers, this may vary.

The glob that you think should work actually does work, when used as a 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' ]

EDIT: Oh, I see, you want to only match things at any folder depth that do not have any docs path parts anywhere in the path. No, that is not possible to do in a way that supports arbitrary depth, as a glob or a minimatch pattern. You'll have to use excludes, or construct a glob that looks like: {!(docs),!(docs)/!(docs),!(docs)/!(docs)/!(docs),!(docs)/!(docs)/!(docs)/!(docs)}/*.js

Otherwise, a path like x/docs/y/z.js will match against **/!(docs)/**/*.js by saying that the first ** matches nothing, the !(docs) matches against x, the next ** matches against docs/y and then *.js matches against z.js.

I got closer, with the following:

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

globtester

Still trying to get it to work for arbitrary depth.

本文标签: javascriptHow to write a single minimatch glob that matches all js files not in a directoryStack Overflow