Golang : Find and replace data in all files recursively



Tags : golang search-recursively search-and-replace filepath

Alright, this tutorial is an enhancement of previous tutorial on how to search for file recursively with wildcard support. In this tutorial, we will search for files that matches the search criteria and replace data inside the files with replacement data. Kinda like refactoring. Here you go! package main import ( "bytes" "fmt" "io" "io/ioutil" "math/rand" "os" "path/filepath" "time" ) var ( targetFolder string targetFile string searchData string replaceData string searchResult []string ) func findFile(path string, fileInfo os.FileInfo, err error) error { // recording in progress ticker. From good old DOS days. ticker := []string{ "-", "\\", //<--- need escape "/", "|", rand.Seed(time.Now().UnixNano()) 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) fmt.Printf("\rSearching and replacing data in file(s) .... [%v]", ticker[rand.Intn(len(ticker)-1)]) // 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) add = "Creating backup copy of " + absolute originalFile, err := os.Open(absolute) if err != nil { fmt.Println(err) defer originalFile.Close() searchResult = append(searchResult, add) backup := absolute + ".bak" backupFile, err := os.Create(backup) if err != nil { fmt.Println(err) defer backupFile.Close() // do the actual work _, err = io.Copy(backupFile, originalFile) if err != nil { panic(err) add = "Backing up to " + backup searchResult = append(searchResult, add) //covert *os.File to []byte originalFileBytes, _ := ioutil.ReadFile(absolute) // ok, now we want to replace the data inside the file replaced := bytes.Replace(originalFileBytes, []byte(searchData), []byte(replaceData), -1) if err = ioutil.WriteFile(absolute, replaced, 0666); err != nil { panic(err) add = "Successfully replaced the target data with replacement data" searchResult = append(searchResult, add) return nil func main() { if len(os.Args) != 5 { fmt.Printf("USAGE : %s <target_directory> <target_file> <search> <replace> \n", os.Args[0]) os.Exit(0) targetFolder = os.Args[1] targetFile = os.Args[2] searchData = os.Args[3] replaceData = os.Args[4] fmt.Println("Searching for [", targetFile, "]") fmt.Println("Starting from directory [", targetFolder, "]") fmt.Println("Replacing [", searchData, "] with [", replaceData, "]") // 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("\[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@") for _, v := range searchResult { fmt.Println(v) Sample usage: Let's replace all the "FileSystem" words in ALL the file.go files found in ALL the sub-directories under /Users/sweetlogic ./main ../. file.go "FileSystem" "SystemFile" Searching for [ file.go ] Starting from directory [ ../. ] Replacing [ FileSystem ] with [ SystemFile ] Searching and replacing data in file(s) .... [-] @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Found : /Users/sweetlogic/.go/src/golang.org/x/net/webdav/file.go Creating backup copy of /Users/sweetlogic/.go/src/golang.org/x/net/webdav/file.go Backing up to /Users/sweetlogic/.go/src/golang.org/x/net/webdav/file.go.bak Successfully replaced the target data with replacement data Inspecting the /Users/sweetlogic/.go/src/golang.org/x/net/webdav/file.go file will show that the word FileSystem replaced by SystemFile. Hope this helps and happy coding! References: https://www.socketloop.com/tutorials/golang-command-line-ticker-to-show-work-in-progress https://socketloop.com/tutorials/golang-simple-file-scaning-and-remove-virus-example https://socketloop.com/tutorials/golang-search-folders-for-file-recursively-with-wildcard-support

  See also : Golang : Search folders for file recursively with wildcard support



Tags : golang search-recursively search-and-replace filepath

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

Advertisement