实现 tree 命令March 4, 2024 · TechnologyTree FULL package main import ( "fmt" "io/fs" "os" "path/filepath" "sort" "strings" ) func sortEntryByName(entries []fs.DirEntry) []fs.DirEntry { sort.Slice(entries, func(i, j int) bool { return entries[i].Name() < entries[j].Name() }) return entries } func printTree(dirPath string, level int, prefix string) { indent := strings.Repeat(" ", level*3) if level > 0 { prefix = prefix + indent + "|" } tmpPrefix := prefix entries, err := os.ReadDir(dirPath) if err != nil { fmt.Println(prefix + "─ ─ " + dirPath + " (Permission denied)") return } if level == 0 { fmt.Println(dirPath) } entries = sortEntryByName(entries) for i, entry := range entries { entryPath := filepath.Join(dirPath, entry.Name()) isDir := entry.IsDir() fi, err := entry.Info() if err != nil { continue } isLink := fi.Mode()&os.ModeSymlink != 0 var entryStr string if isLink { target, _ := os.Readlink(entryPath) entryStr = fmt.Sprintf("%s -> %s", entry.Name(), target) } else { entryStr = entry.Name() } isLast := i == len(entries)-1 if isLast { // last element prefix = prefix[:len(prefix)-1] + "`" } if isDir { fmt.Println(prefix + "─ ─ " + entryStr) if isLast { printTree(entryPath, level+1, tmpPrefix[:len(prefix)-1]) } else { printTree(entryPath, level+1, tmpPrefix) } } else { fmt.Println(prefix + "─ ─ " + entryStr) } } } func main() { var targetPath string if len(os.Args) != 2 { targetPath = "." } else { targetPath = os.Args[1] } _, err := os.Stat(targetPath) if os.IsNotExist(err) { fmt.Println("Error: target dir path not exists.") os.Exit(0) } printTree(targetPath, 0, "|") }