返回列表

gulp的src方法

默认分类 2015/09/16 07:16

https://realguess.net/tags/minimatch/
https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html

在看gulp.src的是实现时,发现src,dest模块是vinyl-fs实现的,而vinyl-fs又是通过minimatch实现的, 最终顺藤摸瓜终于找到了比较官方的文档(第一个链接).

Extended Pattern Matching

Bash supports extended pattern matching. By using the built-in utility we can check if it is enabled or not:

$ shopt extglob

If not, to enable it:

$ shopt -s extglob

By default extglob is on in interactive shells, but off in non-interactive shells.

The key about extended pattern matching is pattern list via | (what we usually see as a OR operator). But do not think about it as that, think about it as a list of array pattern that are separated by | instead of ,. And actually one of them is the same as {} or brace expansion, but it can do more than expanding.

Here are the pattern operators:

? * + @ !

Create some example files:

$ touch a{,1,2,11,12}.js && ls
a11.js  a12.js  a1.js  a2.js  a.js

?(pattern-list)

Zero or one (any one) occurrence of the giving pattern:

$ ls a?(2|1).js
a1.js  a2.js  a.js

*(pattern-list)

Zero or more occurrences of the giving pattern (essentially everything):

$ ls a*(2|1).js
a11.js  a12.js  a1.js  a2.js  a.js

+(pattern-list)

One or more of the giving pattern (notice a.js is missing):

$ ls a+(2|1).js
a11.js  a12.js  a1.js  a2.js

@(pattern-list)

Any one of giving pattern:

$ ls a@(2|1).js
a1.js  a2.js

!(pattern-list)

None of the giving pattern:

$ ls a!(2|1).js
a11.js  a12.js  a.js

One mistake I had was getting confused between extended pattern matching and brace expansion, for example:

$ ls test/@{src|spec}/*.js
ls: cannot access test/@src/*.js: No such file or directory
ls: cannot access test/@spec/*.js: No such file or directory

Extended pattern uses parentheses () not braces {} as in brace expansion.

Also, these two patterns are the same:

test/@(src|spec)/*.js
test/{src,spec}/*.js

In some situations, extended pattern matching does not work, for example, matching files from the current directory and from one of the subdirectories with the following directory structure:

$ tree
.
├── app.js
├── lib
│   └── util.js
└── test
    └── main.js
2 directories, 3 files

I would like to match js files from the current directory and lib/ directory, sort of like:

$ ls *.js lib/*.js
app.js  lib/util.js

But this does not do it:

$ ls @(.|lib)/*.js

Instead, use brace expansion:

$ ls {.,lib}/*.js

Finally, Node’s Minimatch supports brace expansion, extended globbing and globstar.

=====================================================================================

3.5.8.1 Pattern Matching

Any character that appears in a pattern, other than the special pattern characters described below, matches itself. The NUL character may not occur in a pattern. A backslash escapes the following character; the escaping backslash is discarded when matching. The special pattern characters must be quoted if they are to be matched literally.

The special pattern characters have the following meanings:

`*`

Matches any string, including the null string. When the globstar shell option is enabled, and ‘’ is used in a filename expansion context, two adjacent ‘’s used as a single pattern will match all files and zero or more directories and subdirectories. If followed by a ‘/’, two adjacent ‘*’s will match only directories and subdirectories.

`?`

Matches any single character.

`[…]`

Matches any one of the enclosed characters. A pair of characters separated by a hyphen denotes a range expression; any character that falls between those two characters, inclusive, using the current locale’s collating sequence and character set, is matched. If the first character following the ‘[’ is a ‘!’ or a ‘^’ then any character not enclosed is matched. A ‘-’ may be matched by including it as the first or last character in the set. A ‘]’ may be matched by including it as the first character in the set. The sorting order of characters in range expressions is determined by the current locale and the values of the LC_COLLATE and LC_ALL shell variables, if set.

For example, in the default C locale, ‘[a-dx-z]’ is equivalent to ‘[abcdxyz]’. Many locales sort characters in dictionary order, and in these locales ‘[a-dx-z]’ is typically not equivalent to ‘[abcdxyz]’; it might be equivalent to ‘[aBbCcDdxXyYz]’, for example. To obtain the traditional interpretation of ranges in bracket expressions, you can force the use of the C locale by setting the LC_COLLATE or LC_ALL environment variable to the value ‘C’, or enable the globasciiranges shell option.

Within ‘[’ and ‘]’, character classes can be specified using the syntax [:class:], where class is one of the following classes defined in the POSIX standard:

alnum   alpha   ascii   blank   cntrl   digit   graph   lower
print   punct   space   upper   word    xdigit

A character class matches any character belonging to that class. The word character class matches letters, digits, and the character ‘_’.

Within ‘[’ and ‘]’, an equivalence class can be specified using the syntax [=c=], which matches all characters with the same collation weight (as defined by the current locale) as the character c.

Within ‘[’ and ‘]’, the syntax [.symbol.] matches the collating symbol symbol.

If the extglob shell option is enabled using the shopt builtin, several extended pattern matching operators are recognized. In the following description, a pattern-list is a list of one or more patterns separated by a ‘|’. Composite patterns may be formed using one or more of the following sub-patterns:

`?(<var>pattern-list</var>)`

Matches zero or one occurrence of the given patterns.

`*(<var>pattern-list</var>)`

Matches zero or more occurrences of the given patterns.

`+(<var>pattern-list</var>)`

Matches one or more occurrences of the given patterns.

`@(<var>pattern-list</var>)`

Matches one of the given patterns.

`!(<var>pattern-list</var>)`

Matches anything except one of the given patterns.