《Shell 转 Go》
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

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)
	}
}

需要注意的是:

  1. entry.Name 得到的时候 文件名, 不包含路径。 使用 filepath 进行拼接, 获取 完整 的相对路径。
  2. entry.IsDir 判断为真的时候, 调用了 walk 函数本身, 进入下一级目录,进行递归查找。
  3. 使用 strings.HasSuffix 判断文件名是否具有某些特定结尾, 类似需求中的 *.md
  4. handler(name) 中传入文件路径, 类似使用 | xargs <do_something> 时的 标准输入handler 是一个自定义函数, 可以执行任何处理。

在使用的时候, 将 remove 作为参数端的, 类似 xargs 后面接的命令。

func OsWalkDelete() {
	walk("/path/2/somefolder", remove)
}