Gitart
10/29/2016 - 3:30 PM

Replace all

Replace all

// Source: https://gist.github.com/tdegrunt/045f6b3377f3f7ffa408

// Example: replaceall.exe -find="cordove" -replace="gowebapp" -extension="*.go" -filename=true -write=false

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

func visit(path string, fi os.FileInfo, err error) error {

	if err != nil {
		return err
	}

	if fi.IsDir() {
		return nil
	}

	matched, err := filepath.Match(*flagExt, fi.Name())

	if err != nil {
		panic(err)
		return err
	}

	// If the file extension matches
	if matched {
		// Read the entire file into memory
		read, err := ioutil.ReadFile(path)
		if err != nil {
			fmt.Println("**ERROR: Could not read from", path)
			return nil
		}

		// Convert the bytes array into a string
		oldContents := string(read)

		// If the file name contains the search term, replace the file name
		if *flagName && strings.Contains(fi.Name(), *flagFind) {
			oldpath := path
			path = strings.Replace(path, *flagFind, *flagReplace, -1)

			fmt.Println(" Rename:", oldpath, "("+path+")")

			if *flagCommit {
				errRename := os.Rename(oldpath, path)
				if errRename != nil {
					fmt.Println("**ERROR: Could not rename", oldpath, "to", path)
					return nil
				}
			}
		}

		// If the file contains the search term
		if strings.Contains(oldContents, *flagFind) {

			// Replace the search term
			newContents := strings.Replace(oldContents, *flagFind, *flagReplace, -1)

			count := strconv.Itoa(strings.Count(oldContents, *flagFind))

			fmt.Println("Replace:", path, "("+count+")")

			// Write the data back to the file
			if *flagCommit {
				err = ioutil.WriteFile(path, []byte(newContents), 0)
				if err != nil {
					fmt.Println("**ERROR: Could not write to", path)
					return nil
				}
			}
		}
	}

	return nil
}

var (
	flagFind    *string
	flagReplace *string
	flagExt     *string
	flagName    *bool
	flagCommit  *bool
)

func init() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s -find=\"blue\" -replace=\"red\" \n*Does not rename folders\n\nPossible flags:\n", os.Args[0])
		flag.PrintDefaults()
	}
}

func main() {

	flagFind = flag.String("find", "", "search for text")
	flagReplace = flag.String("replace", "", "replace with text")
	flagExt = flag.String("extension", "*.txt", "file extension")
	flagName = flag.Bool("filename", false, "include file path when replacing")
	flagCommit = flag.Bool("write", false, "write the changes (only show changes by defaults)")
	flag.Parse()

	if *flagExt != "" && (*flagFind != "" || *flagReplace != "") {
		fmt.Println()
		if *flagCommit {
			fmt.Println("Results")
			fmt.Println("-------")
		} else {
			fmt.Println("Results (no changes)")
			fmt.Println("--------------------")
		}
		err := filepath.Walk(".", visit)
		if err != nil {
			panic(err)
		}
	} else {
		fmt.Println("Flags are missing. No changes made.")
	}
}