Skip to content

Instantly share code, notes, and snippets.

@benhoyt
Created June 8, 2022 01:25
Show Gist options
  • Save benhoyt/c3462407af4ab9591d59b79015c02d31 to your computer and use it in GitHub Desktop.
Save benhoyt/c3462407af4ab9591d59b79015c02d31 to your computer and use it in GitHub Desktop.
Simple glob matcher in Go
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "usage: glob [path/]pattern\n")
os.Exit(1)
}
dir, pattern := filepath.Split(os.Args[1])
if dir == "" {
dir = "."
}
entries, err := os.ReadDir(dir)
if err != nil {
fmt.Fprintf(os.Stderr, "error listing directory: %v\n", err)
os.Exit(1)
}
for _, entry := range entries {
name := entry.Name()
if match(pattern, name) {
fmt.Println(name)
}
}
}
func match(pattern, name string) bool {
for pattern != "" {
p := pattern[0]
pattern = pattern[1:]
switch p {
case '*':
for pattern != "" && pattern[0] == '*' {
pattern = pattern[1:]
}
for i := 0; i <= len(name); i++ {
if match(pattern, name[i:]) {
return true
}
}
return false
case '?':
if name == "" {
return false
}
default:
if name == "" || p != name[0] {
return false
}
}
name = name[1:]
}
return name == ""
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment