TypechoJoeTheme

至尊技术网

统计
登录
用户名
密码

Golang如何实现文件内容搜索与统计

2025-11-13
/
0 评论
/
3 阅读
/
正在检测是否收录...
11/13

核心需求与设计思路

假设我们有一个项目目录,包含数百个.log.txt文件,需要查找所有包含“error”关键字的行,并统计其出现频率。理想情况下,程序应支持指定目录、过滤文件类型、忽略大小写,并能输出匹配行数及文件分布。

为实现这一目标,我们将模块化设计:使用filepath.Walk遍历目录,os.Open读取文件,bufio.Scanner逐行解析,配合strings.Contains或正则表达式进行匹配,最后通过sync.Map安全地统计结果。

文件遍历与筛选

首先,定义一个结构体承载搜索参数:

go type SearchConfig struct { RootDir string Keyword string CaseSensitive bool FileExt string // 如 ".log" }

利用filepath.Walk递归进入子目录。在遍历过程中,判断文件扩展名是否匹配,跳过目录和不相关文件:

go err := filepath.Walk(config.RootDir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() || !strings.HasSuffix(info.Name(), config.FileExt) { return nil } // 处理单个文件 processFile(path, config, results) return nil })

这里results是一个线程安全的映射,用于收集每个文件中的匹配行。

高效读取与内容匹配

对每个符合条件的文件,使用os.Open打开并交由bufio.Scanner按行处理。这种方式内存友好,适合大文件:

go
file, err := os.Open(filePath)
if err != nil {
log.Printf("无法打开文件 %s: %v", filePath, err)
return
}
defer file.Close()

scanner := bufio.NewScanner(file)
lineNum := 0
for scanner.Scan() {
lineNum++
line := scanner.Text()
match := false
if config.CaseSensitive {
match = strings.Contains(line, config.Keyword)
} else {
match = strings.Contains(
strings.ToLower(line),
strings.ToLower(config.Keyword))
}
if match {
// 安全写入共享map
results.Store(filePath, append(getLines(results, filePath), LineMatch{
Line: lineNum, Content: line}))
}
}

其中LineMatch结构体记录行号和内容,便于后续展示。

并发优化与结果汇总

为提升性能,可将文件处理放入goroutine。由于多个协程会同时写入results,必须使用sync.Map保证并发安全。主协程通过WaitGroup等待所有任务完成:

go var wg sync.WaitGroup for _, file := range files { wg.Add(1) go func(f string) { defer wg.Done() processFile(f, config, results) }(file) } wg.Wait()

搜索结束后,遍历results统计总匹配行数、涉及文件数,并可进一步分析高频关键词(如结合map[string]int统计词频)。

实际应用场景扩展

该工具不仅适用于日志排查,还可用于代码审计(查找敏感函数调用)、数据清洗(提取特定格式内容)等场景。通过引入正则表达式支持,能实现更复杂的模式匹配;添加JSON输出选项,则便于与其他系统集成。

整个实现不足200行代码,却具备良好的扩展性与实用性。Golang的静态编译特性使其可直接部署在服务器上,无需依赖环境,真正做到了“一次编写,随处运行”。

朗读
赞(0)
版权属于:

至尊技术网

本文链接:

https://www.zzwws.cn/archives/38520/(转载时请注明本文出处及文章链接)

评论 (0)

人生倒计时

今日已经过去小时
这周已经过去
本月已经过去
今年已经过去个月

最新回复

  1. 强强强
    2025-04-07
  2. jesse
    2025-01-16
  3. sowxkkxwwk
    2024-11-20
  4. zpzscldkea
    2024-11-20
  5. bruvoaaiju
    2024-11-14

标签云