find 递归查找
在 Linux 中, find
是一个很强大的命令, 不仅能 递归 遍历所有子目录, 还提供了丰富的参数进行过滤。 更重要的是, 可以通过 管道 + xargs
将结果提供给其他命令。
$ find ./ -type f -name "*.md"
$ find ./ -type f -name "*.md" | xargs rm -f
在 Go 中, 同样使用 os.ReadDir
获取当前目录信息, 当目标是 文件夹 的时候进行递归遍历。
// 递归查找
func walk(name string, handler func(name string)) {
entries, err := os.ReadDir(name)
if err != nil {
panic(err)
}
for _, entry := range entries {
// (0) 获取 完整 的相对路径
name := filepath.Join(name, entry.Name())
if entry.IsDir() {
// (1) 递归查找
walk(name, handler)
}
// (2) 过滤参数: -type f
if strings.HasSuffix(name, ".md") {
// _ = os.Remove(name)
// (3) 管道应用 | xargs rm -f
handler(name)
}
}
}
// rm -f
func remove(name string) {
err := os.Remove(name)
if err != nil {
panic(err)
}
}
需要注意的是:
entry.Name
得到的时候 文件名, 不包含路径。 使用filepath
进行拼接, 获取 完整 的相对路径。- 在
entry.IsDir
判断为真的时候, 调用了walk
函数本身, 进入下一级目录,进行递归查找。 - 使用
strings.HasSuffix
判断文件名是否具有某些特定结尾, 类似需求中的*.md
- 向
handler(name)
中传入文件路径, 类似使用| xargs <do_something>
时的 标准输入。handler
是一个自定义函数, 可以执行任何处理。
在使用的时候, 将 remove
作为参数端的, 类似 xargs
后面接的命令。
func OsWalkDelete() {
walk("/path/2/somefolder", remove)
}