Support Multiple File Paths
If you want to support multiple file paths like this, you need to tune flag
parsing logic again.
gorep pattern file1.txt file2.txt file3.txt
# Or
gorep pattern *.txt
Note:
Using*.txt
as an argument in the command line directly may not work as expected because the shell (e.g., Bash) is responsible for expanding wildcard patterns like*.txt
. Theflag
module in Go won't automatically perform this expansion.
However, you can use thefilepath.Glob
function to manually expand the wildcard pattern.
Add multiple paths version grep
in pkg/grep/search.go:
func GrepMulti(pattern string, filePaths []string, options *Options) (MatchResult, error) {
if len(filePaths) == 0 {
return Grep(pattern, "", options)
}
result := make(MatchResult)
for _, filePath := range filePaths {
grepResult, err := Grep(pattern, filePath, options)
if err != nil {
return nil, err
}
for k, v := range grepResult {
result[k] = v
}
}
return result, nil
}
func GrepRecursiveMulti(pattern string, dirPaths []string, options *Options) (MatchResult, error) {
result := make(MatchResult)
for _, dirPath := range dirPaths {
grepResult, err := GrepRecursive(pattern, dirPath, options)
if err != nil {
return nil, err
}
for k, v := range grepResult {
result[k] = v
}
}
return result, nil
}
Modify the flag
part and call multiple paths version functions in main.go:
@@ -36,9 +36,9 @@ func main() {
flag.Usage()
os.Exit(0)
}
- pattern, filePath := args[0], ""
+ pattern, filePaths := args[0], []string{}
if len(args) > 1 {
- filePath = args[1]
+ filePaths = args[1:]
}
options := &grep.Options{}
@@ -52,13 +52,13 @@ func main() {
var result grep.MatchResult
var err error
- if *recursiveFlag && filePath != "" {
- result, err = grep.GrepRecursive(pattern, filePath, options)
+ if *recursiveFlag && len(filePaths) > 0 {
+ result, err = grep.GrepRecursiveMulti(pattern, filePaths, options)
if err != nil {
log.Fatal("Failed to do recursive grep, error:", err)
}
} else {
- result, err = grep.Grep(pattern, filePath, options)
+ result, err = grep.GrepMulti(pattern, filePaths, options)
if err != nil {
log.Fatal("Failed to grep, error:", err)
}
Then you can do this:
gorep -n result pkg/grep/*go
# Or
gorep -n result pkg/grep/search.go pkg/grep/search_test.go
Result:
pkg/grep/search.go:
31: result := make(MatchResult)
38: result[k] = v
41: return result, nil
75: func GrepCount(result MatchResult) int {
77: for _, v := range result {
84: result := make(MatchResult)
91: result[k] = v
94: return result, nil
98: results := make(MatchResult)
105: result, grepErr := Grep(pattern, filePath, options)
109: results[filePath] = result[filePath]
116: return results, nil
pkg/grep/search_test.go:
32: result, err := Grep(pattern, tmpfile.Name(), options)
42: if !reflect.DeepEqual(result, expectedResult) {
43: t.Errorf("Expected %v, but got %v", expectedResult, result)
50: result := make(MatchResult)
51: count := GrepCount(result)
59: result := MatchResult{
68: count := GrepCount(result)
108: result, err := GrepRecursive(pattern, tmpdir, options)
127: if !reflect.DeepEqual(result, expectedResult) {
128: t.Errorf("Expected %v, but got %v", expectedResult, result)
Congratulations🎉! You've made a great CLI app in Go now.
Complete code: https://github.com/Literank/lr_gorep
Keep Going! Keep Learning!