看起来Go
是为数不多的几种语言之一,似乎不理解双星号(“globstar”)文件匹配语法。至少这个语法不像预期的那样工作:
filepath.Glob(dir + "/**/*.bundle/*.txt")
关于 filepath
的实现,我是否漏掉了什么?有没有支持它的库?
filepath.Glob
的实现在内部使用 filepath.Match
。结果发现该规范并不涵盖相当常见的双星号模式(.gitignore
、zsh
)。虽然不完全相同,但对于我的用例,我成功地通过这个小函数解决了它:
func glob(dir string, ext string) ([]string, error) {
files := []string{}
err := filepath.Walk(dir, func(path string, f os.FileInfo, err error) error {
if filepath.Ext(path) == ext {
files = append(files, path)
}
return nil
})
return files, err
}
我仍然期待有更好的实现方式,能够正确地进行双星匹配。
[]string
是字符串的切片,但是[]string{}
是什么意思?为什么要在末尾添加{}?谢谢。 - Leahcim[]string{}
是一个切片字面量,功能上等同于make([]string, 0)
。 - JimBmatches, err := filepathx.Globs(strings.Split(glob, "**")).Expand()
。https://github.com/yargevad/filepathx - Dave Gray我编写了一个小型的扩展库,支持双星号全局匹配。有了这个目录结构:
$ find a
a
a/b
a/b/c.d
a/b/c.d/e.f
a/**/*.*
来匹配包含点的在a
目录下的所有内容,如下所示:package main
import (
"fmt"
"github.com/yargevad/filepathx"
)
func main() {
matches, err := filepathx.Glob("./a/**/*.*")
if err != nil {
panic(err)
}
for _, match := range matches {
fmt.Printf("MATCH: [%v]\n", match)
}
}
这将输出:
$ go run example.go
MATCH: [a/b/c.d]
MATCH: [a/b/c.d/e.f]
这里有类似的东西。你可以传递一个回调函数来过滤文件:
package main
import (
"io/fs"
"path/filepath"
)
func glob(root string, fn func(string)bool) []string {
var files []string
filepath.WalkDir(root, func(s string, d fs.DirEntry, e error) error {
if fn(s) {
files = append(files, s)
}
return nil
})
return files
}
func main() {
files := glob(".", func(s string) bool {
return filepath.Ext(s) == ".txt"
})
for _, file := range files {
println(file)
}
}
filepath.Glob
应该支持**
? - JimB**
并不是一个标准的东西。文档非常明确:'*' 匹配任何非分隔符字符序列
。http://golang.org/pkg/path/filepath/#Match - JimBMatch
被使用了,但这对于文档来说应该是无关紧要的。至少应该提供一个参考。 - tcurdt**
更常见,存在更长时间),但我也不会认为它支持这些模式。 - JimB