Is there no way to list directories only using Golang Glob?

huangapple go评论169阅读模式
英文:

Is there no way to list directories only using Golang Glob?

问题

Golang的Glob函数的行为与我预期的不同。假设我有一个名为"foo"的目录,其结构如下:

foo
|-- 1.txt
|-- 2.csv
|-- 3.json
|-- bar
`-- baz

我想要使用glob模式只获取"foo"目录下的"bar"和"baz"目录。所以我尝试了以下代码:

path = "foo/*/"
matches, err := filepath.Glob(path)
if err != nil {
    log.Fatal(err)
}
fmt.Println(matches)

但是这样并没有匹配到任何结果:

[]

如果我去掉路径末尾的斜杠,将path改为"foo/*",那么我会得到文件和目录的列表,这不是我想要的结果:

[foo/1.txt foo/2.csv foo/3.json foo/bar foo/baz]

我期望的是,如果路径末尾有斜杠,Glob函数应该只返回与glob模式匹配的目录。我在GitHub上发现了同样的问题,但是没有找到解决方法,这可能是一个bug,或者是一个文档不完善的特性,或者只是缺少了一个期望的功能。

我查看了Golang的Match函数的文档,该函数被Glob函数使用,但是文档中没有提到路径末尾的斜杠。

所以基本上,是否有一种解决方法可以使用Glob函数只获取特定路径下的目录,或者我需要使用其他方法来完成这个任务?

英文:

Golang Glob doesn't behave the way I expected it to. Let's say I have a directory "foo" with the following structure:

foo
|-- 1.txt
|-- 2.csv
|-- 3.json
|-- bar
`-- baz

I want to do a glob that gets only the directories "bar" and "baz" within foo. So I try this:

path = "foo/*/"
matches, err := filepath.Glob(path)
if err != nil {
	log.Fatal(err)
}
fmt.Println(matches)

This produces no matches:

[]

If I remove the last trailing slash and change path to "foo/*", I get both files and directories, which is not the result I want:

[foo/1.txt foo/2.csv foo/3.json foo/bar foo/baz]

I would expect that if a trailing slash is present, Glob would return only directories that match the glob pattern. I see that the same issue is noted on GitHub, but couldn't see any workaround for it - it sounds either like a bug, a poorly documented feature, or simply a lack of an expected feature.

I've checked the Go docs for the Match function, which Glob uses, and it doesn't mention anything about a trailing slash.

So basically: is there a workaround so that I can glob only directories under a certain path using Glob, or do I need to use another method for this task?

答案1

得分: 5

你可以遍历匹配列表,并对每个匹配项调用os.Stat。os.Stat返回一个描述文件的FileInfo结构,并包含一个名为IsDir的方法,用于检查文件是否为目录。
示例代码:

// 注意:忽略错误。
matches, _ := filepath.Glob("foo/*")
var dirs []string
for _, match := range matches {
    f, _ := os.Stat(match)
    if f.IsDir() {
        dirs = append(dirs, match)
    }
}
英文:

You can iterate through the list of matches and call os.Stat on each of them. os.Stat returns a FileInfo structure describing the file and it includes a method called IsDir for checking if a file is a directory.
Sample code:

// Note: Ignoring errors.
matches, _ := filepath.Glob("foo/*")
var dirs []string
for _, match := range matches {
    f, _ := os.Stat(match)
    if f.IsDir() {
        dirs = append(dirs, match)
    }
}

huangapple
  • 本文由 发表于 2021年6月2日 22:39:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/67807299.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定