Как сделать корректнй вывод утилиты tree
Задача сделать читаемый вывод прграммы tree. Вывод должен быть таким же как в ситемной утилите tree в linux. У меня есть код, который получает дерево, но не получается сделать правильные отступы чтобы показать вложенность одного фала/папки в другой.
package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
func main() {
GetDirs(".")
}
func GetDirs(pwd string) {
filepath.Walk(pwd, func(path string, info os.FileInfo, err error) (ok error) {
if info.IsDir() {
fmt.Println(path)
pwd = path
GetFiles(pwd)
}
return ok
})
}
func GetFiles(pwd string) {
files, _ := ioutil.ReadDir(pwd)
for _, file := range files {
if !file.IsDir() {
fmt.Println("\t|__", file.Name())
}
}
}
С помощью приведенного кода я получаю путь и файлы в этом пути. Но директории, независимо от того в какую директорию они вложены, все на одном уровне выводятся. Как сделать чтобы вложенность была ясна в выводе? Приложу пример вывода tree встроенной в линукс. Нужно так же.
/home/user/goprogs
├── anonfunc
│ └── anon.go
├── arriter
│ ├── arit.go
│ ├── __debug_bin
│ └── nwefolder
├── async
│ └── main.go
├── channels
│ └── main.go
├── defer
│ └── defer.go
├── from
│ ├── functions
│ │ └── publ.go
│ └── main.go
├── goroutunes
│ └── main.go
├── hell
│ ├── hell.go
│ └── workspace.code-workspace
├── hz
│ └── main.go
├── intrfcs
│ └── main.go
├── intrfcs(r)
│ └── main.go
├── main.go
├── map
│ └── main.go
├── marshall\unmarshall
│ └── main.go
├── multi
│ └── main.go
├── obinob
│ └── main.go
├── Screenshot_20210212-175610_DuckDuckGo.jpg
├── self
│ ├── intrfcs
│ │ └── main.go
│ └── tree
│ ├── dir1
│ │ ├── asdfa
│ │ ├── asdgghh
│ │ └── dir4
│ │ ├── dir5
│ │ │ ├── dkjhf
│ │ │ └── ksdhhhh
│ │ ├── test
│ │ └── test1
│ ├── dir2
│ │ ├── dir3
│ │ │ ├── lfj
│ │ │ ├── wwee
│ │ │ └── yytt
│ │ └── ttyy
│ └── main.go
├── struct
│ └── structure.go
├── struct(r)
│ └── main.go
├── test
│ └── test.go
├── timers
│ ├── main.go
│ └── туц ащдвук
└── web
└── web.go
Ответы (1 шт):
идея в том, что в каждом из функций нужно знать как печатать. также если зашли уже внутрь GetFiles, то нужно печатать и ее содержимое папок. поэтому нужно обратно вызвать GetDirs.
прикладываю неполноценное решение. чтобы оно было в точности как у tree, то нужно сначала печатать файлы, потом только папки. поэтому внутри filepath.Walk сначала собираем все в кучу, после уже печатаем
p.s. originalPwd нужен только для того, чтобы обрезать пути от нужной до печатуемой
package test
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
)
func Tree(pwd string) {
GetDirs(pwd, pwd, "_")
}
func GetDirs(originalPwd, pwd, shift string) {
filepath.Walk(pwd, func(path string, info os.FileInfo, err error) (ok error) {
if info.IsDir() {
GetFiles(originalPwd, path, shift + " ")
fmt.Println("|" + strings.Repeat("-", len(shift)) + strings.Replace(path, originalPwd, "", -1))
}
return ok
})
}
func GetFiles(originalPwd, pwd, shift string) {
files, _ := ioutil.ReadDir(pwd)
for _, file := range files {
if file.IsDir() {
GetDirs(originalPwd, pwd+ "/"+file.Name(), shift + " ")
} else{
fmt.Println("|" + strings.Repeat(" ", len(shift)) + "|__", file.Name())
}
}
}
func TestA(t *testing.T) {
Tree("../questions")
}
вывод:
=== RUN TestA
| |__ docker-compose.yaml
| |__ test.go
|-------/1139325/jsonb
| |__ main.go
| |__ main_test.go
| |__ tw_test.go
|-------/1139325/test
|----/1139325
| |__ test.go
|----/1139325/jsonb
| |__ main_test.go
| |__ tw_test.go
|----/1139325/test
| |__ api.go
| |__ config_api.go
|----------/jbrains/restapi/operations
| |__ server_error.go
|-------/jbrains/restapi
| |__ config_api.go
|-------/jbrains/restapi/operations
|----/jbrains
| |__ api.go
| |__ config_api.go
|-------/jbrains/restapi/operations
| |__ server_error.go
|----/jbrains/restapi
| |__ config_api.go
|----/jbrains/restapi/operations
| |__ questions1237157.go
|----/main
| |__ test_test.go
| |__ variation_test.go
|----/ser
| |__ t_test.go
|----/test
| |__ a.png
| |__ b.png
| |__ main.go
|----/ui
| |__ a.png
| |__ b.png
| |__ j.json
| |__ main.go
|----/ui2
|-
| |__ docker-compose.yaml
| |__ test.go
|----/1139325/jsonb
| |__ main.go
| |__ main_test.go
| |__ tw_test.go
|----/1139325/test
|-/1139325
| |__ test.go
|-/1139325/jsonb
| |__ main_test.go
| |__ tw_test.go
|-/1139325/test
| |__ api.go
| |__ config_api.go
|-------/jbrains/restapi/operations
| |__ server_error.go
|----/jbrains/restapi
| |__ config_api.go
|----/jbrains/restapi/operations
|-/jbrains
| |__ api.go
| |__ config_api.go
|----/jbrains/restapi/operations
| |__ server_error.go
|-/jbrains/restapi
| |__ config_api.go
|-/jbrains/restapi/operations
| |__ questions1237157.go
|-/main
| |__ test_test.go
| |__ variation_test.go
|-/ser
| |__ t_test.go
|-/test
| |__ a.png
| |__ b.png
| |__ main.go
|-/ui
| |__ a.png
| |__ b.png
| |__ j.json
| |__ main.go
|-/ui2
--- PASS: TestA (0.01s)