Skip to content

Instantly share code, notes, and snippets.

@lobuhi
Last active July 13, 2023 20:56
Show Gist options
  • Save lobuhi/61643c3ab04c7b82b8b75b9d10d564c6 to your computer and use it in GitHub Desktop.
Save lobuhi/61643c3ab04c7b82b8b75b9d10d564c6 to your computer and use it in GitHub Desktop.
Multigrep - Multithreaded grep in go
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"sync"
)
var (
searchString string
rootFolder string
numThreads int
wg sync.WaitGroup
matches []string
)
func main() {
// Parse command line arguments
flag.StringVar(&searchString, "s", "", "String to search for")
flag.StringVar(&rootFolder, "f", "", "Root folder to search in")
flag.IntVar(&numThreads, "t", 10, "Number of threads")
flag.Parse()
if searchString == "" || rootFolder == "" {
log.Fatal("String to search (-s) and root folder (-f) must be provided")
}
err := filepath.Walk(rootFolder, processFile)
if err != nil {
log.Fatal(err)
}
wg.Wait()
if len(matches) == 0 {
fmt.Println("No matches found.")
} else {
for _, match := range matches {
fmt.Println(match)
}
}
}
func processFile(path string, info os.FileInfo, err error) error {
if err != nil {
log.Println(err)
return nil
}
if info.IsDir() {
return nil
}
wg.Add(1)
go func() {
defer wg.Done()
content, err := ioutil.ReadFile(path)
if err != nil {
log.Println(err)
return
}
lines := strings.Split(string(content), "\n")
for _, line := range lines {
if strings.Contains(line, searchString) {
matches = append(matches, line)
}
}
}()
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment