Go言語_ディレクトリ名を再帰して変更する
Go言語でディレクトリ名の一部を変更します。
ディレクトリ名を変更する場合は、再帰処理を用いてサブディレクトリから順番に名前を変更する必要があります。
package main
import (
"errors"
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
)
/*!
* @brief ディレクトリ名を変更する
* @param[in] target 変更対象のディレクトリ名
* @param[in] src 変更前の文字列
* @param[in] dst 変更後の文字列
* @return error エラー情報
*/
func renameDir(target string, src string, dst string) error {
// 変更する文字列が存在するか確認する
dirname, basename := filepath.Split(target)
if !strings.Contains(basename, src) {
return nil
}
// 変更後のファイルパスを作成する
res := strings.Replace(basename, src, dst, -1)
res = filepath.Join(dirname, res)
// 変更する
if err := os.Rename(target, res); err != nil {
return err
}
return nil
}
/*!
* @brief ディレクトリ名を再帰的に変更する
* @param[in] rootDir 変更対象のトップディレクトリ名
* @param[in] src 変更前の文字列
* @param[in] dst 変更後の文字列
* @return error エラー情報
*/
func renameDirRecur(rootDir string, src string, dst string) error {
files, err := ioutil.ReadDir(rootDir)
if err != nil {
return err
}
for _, file := range files {
// ディレクトリのみを対象にする
if !file.IsDir() {
continue
}
// 子要素から名前を変更していく。
subDir := filepath.Join(rootDir, file.Name())
err = renameDirRecur(subDir, src, dst)
if err != nil {
return err
}
err = renameDir(subDir, src, dst)
if err != nil {
return err
}
}
return nil
}
/*!
* @brief 初期化処理
* @retval string ディレクトリ名
* @retval string 変換文字列
* @retval error エラー情報
*/
func initialize() ([]string, bool, error) {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: %s [OPTION]... SOURCE DEST:\n",
filepath.Base(os.Args[0]))
flag.PrintDefaults()
}
optR := flag.Bool("r", false, "recursive mode")
flag.Parse()
if flag.NArg() != 3 {
flag.Usage()
return nil, false, errors.New("Error: Invalid arguments.")
}
return flag.Args(), *optR, nil
}
/*!
* @brief main routine
* @return 成功時には0を返し、失敗時には1を返す。
*/
func main() {
targets, recurMode, err := initialize()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if recurMode {
err = renameDirRecur(targets[0], targets[1], targets[2])
} else {
err = renameDir(targets[0], targets[1], targets[2])
}
if err != nil {
fmt.Println(err)
os.Exit(1)
}
os.Exit(0)
}
コマンド実行例
「dir1」ディレクトリ配下に存在する「abc」ディレクトリを「acb」という名前に変更する場合、下記のように実行します。
go run renamer.go dir1 bc cb
「-r」を付加するとサブディレクトリを含んでディレクトリ名を変更します。
go run renamer.go -r dir2 bc cb
例えば、npmインストールにより生成されたnode_modulesから、ハイフンやドットのような不要文字を削除したい場合、下記のように実行します。
go run renamer.go -r node_modules - ""
go run renamer.go -r node_modules . ""