package main import ( "archive/zip" "bufio" "flag" "fmt" "io/fs" "log" "os" "path/filepath" "strings" "sync" ) var inputDir = flag.String("d", "/", "Dir search") func appendLineToFile(filename string, line string) error { file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { return err } defer file.Close() _, err = file.WriteString(line + "\n") return err } func getAllFiles(root string) ([]string, error) { var files []string err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error { if err != nil { return err } if !d.IsDir() { files = append(files, path) } return nil }) return files, err } func loadStrings() ([]string, error) { log.Println("Loading search.txt") var list []string file, err := os.Open("search.txt") if err != nil { return list, err } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() list = append(list, strings.TrimSpace(line)) log.Println("+", line) } if err := scanner.Err(); err != nil { return list, err } log.Println("Loaded search.txt") return list, nil } func checkArchive(zipPath string, list []string) error { r, err := zip.OpenReader(zipPath) if err != nil { return err } defer r.Close() for _, f := range r.File { if strings.Contains(f.Name, ".txt") { rc, err := f.Open() if err != nil { continue } defer rc.Close() scanner := bufio.NewScanner(rc) for scanner.Scan() { line := scanner.Text() for _, str := range list { if strings.Contains(line, str) { log.Println("Found:", line) result := fmt.Sprintf("%s;%s", line, zipPath) appendLineToFile("result.txt", result) } } } if err := scanner.Err(); err != nil { continue } } } return nil } func threadNew(ch chan string, list []string, wg *sync.WaitGroup) { for zipPath := range ch { log.Println("Check", zipPath) checkArchive(zipPath, list) wg.Done() } } func main() { var wg sync.WaitGroup flag.Parse() list, err := loadStrings() if err != nil { log.Fatalf("fail load search list: %v", err) } files, err := getAllFiles(*inputDir) if err != nil { log.Fatalf("fail load files list: %v", err) } log.Println("Files:", len(files)) ch := make(chan string) for i := 0; i < 10; i++ { go threadNew(ch, list, &wg) } for _, zipPath := range files { wg.Add(1) ch <- zipPath } wg.Wait() }