

Go言語で指定のディレクトリ配下のテキストファイル(再帰的に探索)して、指定した文字列に置換するプログラムを作ったのですが、入力した文字列(ここだとbefore,after)  
を関数visitで利用できるようにするにはどうしたらいいかご存じの方いらっしゃいましたら、ご教授いただければ幸いです。

[code]

    newContents := bytes.Replace(read, before, after, -1)
    
[/code]

のところで使いたいのですが、使えるようにする手段がわからず、困っています。

[code]

    package main
    
    import (
        "bufio"
        "bytes"
        "fmt"
        "io/ioutil"
        "os"
        "path/filepath"
    )
    
    func visit(path string, fi os.FileInfo, err error) error {
    
        if err != nil {
            return err
        }
    
        if !!fi.IsDir() {
            return nil //
        }
    
        matched, err := filepath.Match("*.txt", fi.Name())
    
        if err != nil {
            panic(err)
        }
    
        if matched {
            read, err := ioutil.ReadFile(path)
            if err != nil {
                panic(err)
            }
            fmt.Println(path)
            newContents := bytes.Replace(read, before, after, -1)
            err = ioutil.WriteFile(path, newContents, os.ModePerm)
            if err != nil {
                panic(err)
            }
    
        }
    
        return nil
    }
    
    func main() {
        root := input("ファイルパス")
        before := input("置換前文字列")
        after := input("置換後文字列")
        err := filepath.Walk(root, visit)
        if err != nil {
            panic(err)
        }
    }
    
    func input(msg string) string {
        scanner := bufio.NewScanner(os.Stdin)
        fmt.Print(msg + ":")
        scanner.Scan()
        return scanner.Text()
    }
    
[/code]


CC BY-SA 4.0
2021-05-10T11:55:14.763
75764
2021-05-12T10:03:18.723
2021-05-12T10:01:01.520
45221
question
go
Go言語で指定文字列を置換　(複数テキストファイル対象)


> 入力した文字列(ここだと `before`, `after`)を関数 `visit` で利用できるようにするにはどうしたらいいか

以下は closure(クロージャ)を使う方法です。

[code]

    package main
    
    import (
        "bufio"
        "bytes"
        "fmt"
        "io/ioutil"
        "os"
        "path/filepath"
    )
    
    func input(msg string) string {
        scanner := bufio.NewScanner(os.Stdin)
        fmt.Print(msg + ":")
        scanner.Scan()
        return scanner.Text()
    }
    
    func replaceFileContents(path string, before, after []byte) error {
        read, err := ioutil.ReadFile(path)
        if err != nil {
            return err
        }
    
        fmt.Println(path)
        if bytes.Contains(read, before) {
            newContents := bytes.Replace(read, before, after, -1)
            err = ioutil.WriteFile(path, newContents, os.ModePerm)
            if err != nil {
                return err
            }
        }
    
        return nil
    }
    
    func main() {
        root := input("ファイルパス")
        before := []byte(input("置換前文字列"))
        after := []byte(input("置換後文字列"))
    
        err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
            if err != nil {
                return err
            }
    
            if fi.IsDir() || filepath.Ext(fi.Name()) != ".txt" {
                return nil
            }
    
            return replaceFileContents(path, before, after)
        })
    
        if err != nil {
            panic(err)
        }
    }
    
[/code]


CC BY-SA 4.0
2021-05-10T13:30:10.267
75766
2021-05-12T10:03:18.723
2021-05-12T10:03:18.723
75764
answer