mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 06:47:20 +08:00
101 lines
2.2 KiB
Go
101 lines
2.2 KiB
Go
package io
|
||
|
||
import (
|
||
"os"
|
||
"path/filepath"
|
||
"strings"
|
||
|
||
"github.com/acepanel/panel/pkg/shell"
|
||
)
|
||
|
||
// Search 查找文件/文件夹
|
||
func Search(path, keyword string, sub bool) (map[string]os.FileInfo, error) {
|
||
paths := make(map[string]os.FileInfo)
|
||
baseDepth := strings.Count(filepath.Clean(path), string(os.PathSeparator))
|
||
|
||
err := filepath.Walk(path, func(p string, info os.FileInfo, err error) error {
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if !sub && strings.Count(p, string(os.PathSeparator)) > baseDepth+1 {
|
||
return filepath.SkipDir
|
||
}
|
||
if strings.Contains(info.Name(), keyword) {
|
||
paths[p] = info
|
||
}
|
||
return nil
|
||
})
|
||
|
||
return paths, err
|
||
}
|
||
|
||
// SearchX 查找文件/文件夹(find命令)
|
||
func SearchX(path, keyword string, sub bool) ([]os.DirEntry, error) {
|
||
var out string
|
||
var err error
|
||
if sub {
|
||
out, err = shell.Execf("find '%s' -name '*%s*'", path, keyword)
|
||
} else {
|
||
out, err = shell.Execf("find '%s' -maxdepth 1 -name '*%s*'", path, keyword)
|
||
}
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
var entries []os.DirEntry
|
||
lines := strings.Split(out, "\n")
|
||
for _, line := range lines {
|
||
line = strings.TrimSpace(line)
|
||
if line == "" || line == path {
|
||
continue
|
||
}
|
||
entry, err := newSearchEntryFromPath(line)
|
||
if err != nil {
|
||
continue // 直接跳过,不返回错误,不然很烦人的
|
||
}
|
||
entries = append(entries, entry)
|
||
}
|
||
|
||
return entries, nil
|
||
}
|
||
|
||
// SearchEntry 实现 os.DirEntry 接口
|
||
type SearchEntry struct {
|
||
path string
|
||
info os.FileInfo
|
||
}
|
||
|
||
// newSearchEntryFromPath 根据文件路径创建 SearchEntry
|
||
func newSearchEntryFromPath(path string) (*SearchEntry, error) {
|
||
info, err := os.Lstat(path) // 不跟随符号链接
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return &SearchEntry{path: path, info: info}, nil
|
||
}
|
||
|
||
// Name 返回文件基本名称
|
||
func (d *SearchEntry) Name() string {
|
||
return filepath.Base(d.path)
|
||
}
|
||
|
||
// IsDir 判断是否为目录
|
||
func (d *SearchEntry) IsDir() bool {
|
||
return d.info.IsDir()
|
||
}
|
||
|
||
// Type 返回文件模式类型
|
||
func (d *SearchEntry) Type() os.FileMode {
|
||
return d.info.Mode().Type()
|
||
}
|
||
|
||
// Info 返回文件信息
|
||
func (d *SearchEntry) Info() (os.FileInfo, error) {
|
||
return d.info, nil
|
||
}
|
||
|
||
// Path 返回文件完整路径
|
||
func (d *SearchEntry) Path() string {
|
||
return d.path
|
||
}
|