You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
2.4 KiB
Go
99 lines
2.4 KiB
Go
package search
|
|
|
|
import (
|
|
"b612.me/stario"
|
|
"b612.me/starlog"
|
|
"b612.me/startext"
|
|
"bufio"
|
|
"fmt"
|
|
"github.com/spf13/cobra"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var stFolder string
|
|
var stNum, stMax, stMin int
|
|
var stautoGBK bool
|
|
|
|
func init() {
|
|
Cmd.Flags().StringVarP(&stFolder, "folder", "f", "./", "搜索的文件夹")
|
|
Cmd.Flags().IntVarP(&stNum, "thread-num", "n", 5, "并发搜寻协程数")
|
|
Cmd.Flags().BoolVarP(&stautoGBK, "autogbk", "g", true, "自动GBK识别")
|
|
Cmd.Flags().IntVar(&stMax, "max", 0, "行最大字数")
|
|
Cmd.Flags().IntVar(&stMin, "min", 0, "行最小字数")
|
|
}
|
|
|
|
var Cmd = &cobra.Command{
|
|
Use: "st",
|
|
Short: "搜索文件中特定字符串",
|
|
Long: "搜索文件中特定字符串",
|
|
Run: func(this *cobra.Command, args []string) {
|
|
if len(args) != 2 {
|
|
starlog.Errorln("应当传入两个参数,搜寻文件后缀和搜寻文本")
|
|
os.Exit(1)
|
|
}
|
|
err := searchText(stFolder, args[0], args[1], stNum, stautoGBK, stMax, stMin)
|
|
if err != nil {
|
|
os.Exit(2)
|
|
}
|
|
return
|
|
},
|
|
}
|
|
|
|
func searchText(folder string, filematch string, text string, thread int, autoGBK bool, max, min int) error {
|
|
data, err := ioutil.ReadDir(folder)
|
|
if err != nil {
|
|
starlog.Errorln("read folder failed", folder, err)
|
|
return err
|
|
}
|
|
wg := stario.NewWaitGroup(thread)
|
|
searchFn := func(filepath string, text string) {
|
|
//starlog.Debugln("searching", filepath, text)
|
|
defer wg.Done()
|
|
fp, err := os.Open(filepath)
|
|
if err != nil {
|
|
starlog.Errorln("open file failed", filepath, err)
|
|
return
|
|
}
|
|
defer fp.Close()
|
|
reader := bufio.NewReader(fp)
|
|
count := 0
|
|
for {
|
|
origin, err := reader.ReadString('\n')
|
|
count++
|
|
if stautoGBK && startext.IsGBK([]byte(origin)) {
|
|
originByte, _ := startext.GBK2UTF8([]byte(origin))
|
|
origin = string(originByte)
|
|
}
|
|
origin = strings.TrimSpace(origin)
|
|
if max != 0 && len(origin) > max {
|
|
continue
|
|
}
|
|
if min != 0 && len(origin) < min {
|
|
continue
|
|
}
|
|
if strings.Contains(origin, text) {
|
|
fmt.Printf("file:%s line:%d matched:%s\n", filepath, count, origin)
|
|
}
|
|
if err != nil {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
for _, v := range data {
|
|
if v.IsDir() {
|
|
searchText(filepath.Join(folder, v.Name()), filematch, text, thread, autoGBK, stMax, stMin)
|
|
}
|
|
filepath := filepath.Join(folder, v.Name())
|
|
if matched, _ := regexp.MatchString(filematch, filepath); matched {
|
|
wg.Add(1)
|
|
go searchFn(filepath, text)
|
|
}
|
|
}
|
|
wg.Wait()
|
|
return nil
|
|
}
|