搜索
首页 > 工具开发 > 辅助工具 >

字符串查找工具下载

2025-01-04 20:48:13 浏览:137
字符串查找工具,从指定目录查找包含指定字符串的文件:

编程语言:Go
运行方式:Cli
运行命令:

./程序名称 "指定查找目录" "指定关键词" "线程数"

如:
./find "d:/x" "pass" "20"

下载find.exe


演示


源码


package main

import (
    "bufio"
    "fmt"
    "io/fs"
    "os"
    "path/filepath"
    "strconv"
    "strings"
    "sync"
    "sync/atomic"
    "time"
)

var c = make(chan string, 1000000)  //c通道 传递文件路径
var c2 = make(chan string, 1000000) //c2通道 传递包含关键字的文件路径
var s sync.WaitGroup                //等待组
var count int64 = 0                 //文件总数
var count2 int64 = 0                //包含关键字的文件数
func main() {
    var mulu, search string //目录、关键字
    var xiancheng int       //线程数
    var err error           //错误
    if len(os.Args) > 3 {
        mulu = os.Args[1]   //获取目录
        search = os.Args[2] //获取关键字
        if search == "" {
            panic("没有指定关键字")
        }
        xiancheng, err = strconv.Atoi(os.Args[3]) //获取线程数 字符串转int
        if err != nil {
            xiancheng = 20 //默认线程数
        }
    } else {
        panic("没有指定目录、关键字、线程数")
    }
    var timedata = time.Now() //获取开始时间
    fmt.Println("\n\n启动线程数:", xiancheng)
    for i := 0; i < xiancheng; i++ {
        go gocheak(search) //启动查找线程
        s.Add(1)
    }
    go shouji() //启动收集线程
    fmt.Println("开始查找...")
    err = filepath.WalkDir(mulu, panduan) //遍历目录
    if err != nil {
        panic("指定目录不存在")
    }
    close(c)  //关闭c通道
    s.Wait()  //等待查找线程结束
    s.Add(1)  //添加收集线程等待
    close(c2) //关闭c2通道
    s.Wait()  //等待收集线程结束
    fmt.Println("查找结束,耗时:", time.Since(timedata), ",共计检查", count, "个文件,其中", count2, "个文件包含\"", search, "\"关键字")
    if count2 > 0 {
        fmt.Println("请打开list.html文件查看结果\n\n")
    } else {
        fmt.Println("\n\n")
    }
}

// 判断是否为文件
func panduan(path string, d fs.DirEntry, err error) error {
    if err != nil {
        return err
    }
    if !d.IsDir() {
        c <- path //将文件路径传递给c通道
    }
    return nil
}

// 查找函数
func gocheak(search string) {
    defer s.Done()        //c通道关闭后等待组减1
    for path := range c { //从c通道获取文件路径
        atomic.AddInt64(&count, 1)         //count原子性加1
        if ok := check(path, search); ok { //如果包含关键字
            //fmt.Println(path)
            c2 <- path                  //将包含关键字的文件路径传递给c2通道
            atomic.AddInt64(&count2, 1) //count2原子性加1
        }
    }
}

// 收集函数
func shouji() {
    defer s.Done()
    paths := make([]string, 0) //初始化路径列表
    for path := range c2 {
        paths = append(paths, path) //添加路径到列表
    }
    if len(paths) > 0 { //如果有路径
        var neirong strings.Builder //初始化列表构建器
        neirong.WriteString(`<!DOCTYPE HTML><html><head><title>文件列表</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" /></head><body>`)
        for i, path := range paths { //遍历路径列表
            neirong.WriteString(fmt.Sprintf("%d.<a href='%s' target='_blank'>%s</a><br>", i+1, path, path))
        }
        neirong.WriteString(`</body></html>`)
        dir := filepath.Dir("./list.html") // 确保目录存在
        err := os.MkdirAll(dir, 0755)
        if err != nil {
            return
        }
        file, err := os.Create("./list.html") // 打开或创建文件
        if err != nil {
            return
        }
        defer file.Close()
        _, err = file.Write([]byte(neirong.String())) // 将二进制数据写入文件
        if err != nil {
            return
        }
        err = file.Sync() // 确保所有数据都被写入文件
        if err != nil {
            return
        }
    }
}

// 检查函数
func check(path, search string) bool {
    file, err := os.Open(path) //打开文件
    if err != nil {
        return false
    }
    defer file.Close()
    scanner := bufio.NewScanner(file) //创建扫描器
    for scanner.Scan() {              //逐行扫描
        if strings.Contains(scanner.Text(), search) { //如果包含关键字
            return true
        }
    }
    if err := scanner.Err(); err != nil { //如果出错
        return false
    }
    return false
}


标签:字符串查找工具

相关栏目