Golang : Search folders for file recursively with wildcard support
Ok, here is an example on how to search for a file starting from a target directory and recursively search all its sub-directories. It is pretty similar to https://www.socketloop.com/tutorials/linux-mac-os-x-search-for-files-by-filename-and-extension-with-find-command, but implemented in Golang instead of relying on combination of command line tools.
It supports wildcard search for the filename and perform simple sanity checks on the given search parameters.
Here you go!
NOTES:
If you try to execute ./findFileRecursively ./ *.go
but keep getting the USAGE prompt. Escape the asterisk *
first with \
or /
(Windows) - ./findFileRecursively ./ \*.go
package main
import (
"fmt"
"os"
"path/filepath"
)
var (
targetFolder string
targetFile string
searchResult []string
)
func findFile(path string, fileInfo os.FileInfo, err error) error {
if err != nil {
fmt.Println(err)
return nil
}
// get absolute path of the folder that we are searching
absolute, err := filepath.Abs(path)
if err != nil {
fmt.Println(err)
return nil
}
if fileInfo.IsDir() {
fmt.Println("Searching directory ... ", absolute)
// correct permission to scan folder?
testDir, err := os.Open(absolute)
if err != nil {
if os.IsPermission(err) {
fmt.Println("No permission to scan ... ", absolute)
fmt.Println(err)
}
}
testDir.Close()
return nil
} else {
// ok, we are dealing with a file
// is this the target file?
// yes, need to support wildcard search as well
// https://www.socketloop.com/tutorials/golang-match-strings-by-wildcard-patterns-with-filepath-match-function
matched, err := filepath.Match(targetFile, fileInfo.Name())
if err != nil {
fmt.Println(err)
}
if matched {
// yes, add into our search result
add := "Found : " + absolute
searchResult = append(searchResult, add)
}
}
return nil
}
func main() {
if len(os.Args) != 3 {
fmt.Printf("USAGE : %s <target_directory> <target_file> \n", os.Args[0])
os.Exit(0)
}
targetFolder = os.Args[1]
targetFile = os.Args[2]
fmt.Println("Searching for [", targetFile, "]")
fmt.Println("Starting from directory [", targetFolder, "]")
// sanity check
testFile, err := os.Open(targetFolder)
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
defer testFile.Close()
testFileInfo, _ := testFile.Stat()
if !testFileInfo.IsDir() {
fmt.Println(targetFolder, " is not a directory!")
os.Exit(-1)
}
err = filepath.Walk(targetFolder, findFile)
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
// display our search result
fmt.Println("\n\nFound ", len(searchResult), " hits!")
fmt.Println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
for _, v := range searchResult {
fmt.Println(v)
}
}
Sample output for ./findFileRecursively ./ *main.go
Searching for [ *main.go ]
Starting from directory [ ./ ]
Searching directory ... /Users/sweetlogic
Searching directory ... /Users/sweetlogic/.Trash
Searching directory ... /Users/sweetlogic/.atom
Searching directory ... /Users/sweetlogic/.atom/.apm
Searching directory ... /Users/sweetlogic/.atom/blob-store
Searching directory ... /Users/sweetlogic/.atom/compile-cache
Searching directory ... /Users/sweetlogic/.atom/compile-cache/coffee
...
Found 103 hits!
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Found : /Users/sweetlogic/.go/src/HelloGoglandNonSingle/main.go
Found : /Users/sweetlogic/.go/src/github.com/golang/freetype/example/truetype/main.go
Found : /Users/sweetlogic/.go/src/github.com/golang/lint/testdata/blank-import-main.go
...
Happy coding!
References:
https://www.socketloop.com/tutorials/golang-find-files-by-extension
See also : Linux/MacOSX : Search for files by filename and extension with find command
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+4.8k Unix/Linux : How to test user agents blocked successfully ?
+5.9k Golang : Takes a plural word and makes it singular
+18.8k Golang : Read directory content with os.Open
+12.9k Golang : syscall.Socket example
+32.2k Golang : Create x509 certificate, private and public keys
+11.2k Golang : Search and extract certain XML data example
+7.9k Golang : How to extract video or image files from html source code
+9.2k Golang : How to profile or log time spend on execution?
+4k HTTP common errors and their meaning explained
+9.1k Fix ERROR 1045 (28000): Access denied for user 'root'@'ip-address' (using password: YES)
+12.8k Golang : convert(cast) string to float value
+18k Golang : How to get own program name during runtime ?