go file glob
描述
glob是shell使用的路径匹配符,类似于正则表达式,但是与正则表达式不完全相同。在linux操作中如文件匹配等等其实已经使用了glob通配符。由于其在路径匹配方面的强大,其他语言也有相应的实现。我在使用基于node的gulp时遇到glob匹配文件路径,于是顺便整理一下glob的基础语法和使用。
语法和使用
* :匹配一个路径部分中0个或多个字符,注意不匹配以.开始的路径,如文件.a。
? :匹配一个字符。
[…] :匹配一系列字符,如[abc]匹配字符a, b, c,在[^…]和[!…]表示匹配不在列表中的字符,如[^abc]匹配除了a, b, c以外的字符。
** :匹配0个或多个子文件夹。
{a,b} :匹配a或则b,a和b也是通配符,可以由其他通配符组成。
! :排除文件,如!a.js表示排除文件a.js。
用途和注意点
glob非常强大的用途在于路径匹配,大部分的平台和开发语言都会在配置中使用glob路径匹配,其普遍性几乎使其成为一种标准。但是需注意的是,每个平台和开发语言所支持glob路径匹配可能不完全一样。
Golang Glob
系统自带的filepath.glob(pattern) 是不支持pattern-list {,}
形式的.
github.com/gobwas/glob
编译为给定的模式和字符串(如果模式之后存在)创建Glob作为分隔符。模式语法是:
术语:
`*` 匹配任何非分隔符字符序列 (任意多个字符)
`**` 匹配任何字符序列 (任意多个字符,包含子路径)
`?` 匹配任何单个非分隔符 (任意的一个字符)
`[`[`!`] 字符范围`]`
字符类(必须是非空的)
`{`pattern-list`}`
模式选择
c匹配字符c(c!=`*`,`**`,`?`,`\`,`[`,```,`}`)
`\`c匹配字符c
字符范围:
c匹配字符c(c!=`\\`,`-`,`]`)
`\`c匹配字符c
lo`-`hi匹配lo <= c <= hi的字符c
模式列表:
模式{`,`模式}
逗号分隔(无空格)模式
pattern: { term }
term:
`*` matches any sequence of non-separator characters
`**` matches any sequence of characters
`?` matches any single non-separator character
`[` [ `!` ] { character-range } `]`
character class (must be non-empty)
`{` pattern-list `}`
pattern alternatives
c matches character c (c != `*`, `**`, `?`, `\`, `[`, `{`, `}`)
`\` c matches character c
character-range:
c matches character c (c != `\\`, `-`, `]`)
`\` c matches character c
lo `-` hi matches character c for lo <= c <= hi
pattern-list:
pattern { `,` pattern }
comma-separated (without spaces) patterns
匹配需要匹配所有名称的模式,而不仅仅是一个子字符串。当模式格式错误时,唯一可能返回的错误是 ErrBadPattern 。
这几天打算仔细看下redis命令,到keys * 时,猜测应该使用的是 glob 模式匹配,就详细找了点资料,总结如下:
标准glob 模式:
*
?
[abc]
[a-z]类unix系统,[]还可以使用 '!' - 排除
[!abc]
[!a-z]在shell中,'!' 表示 'history' 命令的替代。所以,[!abc],可以使用 [^abc] 来替代!!
类unix下的一些shell(c shell 和 bash)支持额外的解析,称作:'alternation' 或 'brace expansion' - 花括号扩展({})
1.生成一个集合:echo a{p,c,d,b}e // ape ace ade abe 但是,不应该在shell脚本中使用,shell将本中,会原样输出: echo a{p,c,d,b}e // a{p,c,d,b}e
2.当 {} 同 通配符结合使用,先解析 {},再正常解析通配符。因此:
ls *.{jpg,jpeg,png} // 被解析为:ls *.jpg *.jpeg *.png echo *.{png,jp{e,}g} - {}可以嵌套使用 // 被解析为:*.jpg *.jpeg *.png
3.{} 还可以用于按次序排列的区间,2个整型或字符之间,以 '..' 分割
echo {1..10} echo file{1..4}.txt // - // 新版本的bash允许第3个整型,表示步长 echo {1..10..3} // 输出:1 4 7 10 // - //
4.当 {} 结合变量(variable)一起使用,可能必须结合内建的 'eval' 一起使用。
start = 1; end = 10 echo {$start..$end} // 输出 {1..10} eval echo {$start..$end} // 输出 1 2 3 4 5 6 7 8 9 10
windows下的cmd.exe
不支持 [...]SQL:
标准sql语句的like操作符,支持 ? 和 *,但不支持 []
? == _- == %
glob术语一般不在SQL社区中使用。很多SQL的实现,扩展了like操作符,支持更多的模式匹配
- == %
参考文章:
https://en.wikipedia.org/wiki/Glob_(programming)
https://en.wikipedia.org/wiki/Bash_(Unix_shell)#Brace_expansion
https://en.wikipedia.org/wiki/Wildcard_character
redis的glob模式支持:
?
*
[]
[^]
redis的模式匹配,支持的有点少,stackoverflow上有一篇文章,结合 'lua脚本' ,可匹配更多(我们用php应该也可以)
http://stackoverflow.com/questions/29942541/how-to-get-keys-which-does-not-match-a-particular-pattern-in-redis