// packer - a simple CLI tool to find and zip file corresponding to a given regex // find + zip linux CLI works too package main import ( "fmt" "github.com/akamensky/argparse" "log" "os" fp "path/filepath" re "regexp" ) // parseArguments - get needed arguments to launch the `packer` // returns 3 strings : // * regex // * outputPath // * directory func parseArguments() (string, string, string, error) { parser := argparse.NewParser("packer", "packer - zip file where filenames match with a regex") var err error regex := parser.String("r", "regex", &argparse.Options{Required: true, Help: "filename Regex"}) outputPath := parser.String("o", "output-path", &argparse.Options{Required: true, Help: "zip output path (including zip name)"}) directory := parser.String("d", "directory", &argparse.Options{Required: false, Help: "root directory to check files", Default: "."}) parseError := parser.Parse(os.Args) if parseError != nil { err = fmt.Errorf("parsing error: %s", parseError) } return *regex, *directory, *outputPath, err } // buildRegex - build POSIX regex from a string // WARN: lookahead and lookbehind are not supported func buildRegex(regex string) (*re.Regexp, error) { rc, err := re.CompilePOSIX(regex) return rc, err } // walkFilteredDir - walk into a directory and its subdirectories and find files that match a regex func walkDirFiltered(directory string, regex re.Regexp) ([]string, error) { var files []string err := fp.Walk(directory, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if !info.IsDir() && regex.MatchString(path) { fmt.Println(path) files = append(files, path) } return err }) return files, err } // getFilesFromDirectoryPath - wrapper calling `walkDirFiltered()` func getFilesFromDirectoryPath(directory string, regex re.Regexp) ([]string, error) { files, err := walkDirFiltered(directory, regex) return files, err } func main() { // parse arguments regex, directory, outputPath, err := parseArguments() if err != nil { log.Fatal("error while parsing args : ", err) } // build regex from string rc, err := buildRegex(regex) if err != nil { log.Fatal("error while compiling regex : '", regex, "'\nWARN: lookahead and lookbehind not implemented") } // deferencing Regexp pointer rd := *rc // walk into directory log.Printf("looking for file '%s' in '%s' ...", rd.String(), directory) files, err := getFilesFromDirectoryPath(directory, rd) log.Printf("files found : %d", len(files)) log.Printf("files zipped in %s", outputPath) }