package main import ( "flag" "fmt" "log" "os" "path" "regexp" "strings" "sync" ) func init() { log.SetFlags(log.Lmicroseconds) } func main() { recreate := flag.Bool("f", false, "First rename all files to .bak and then rename them to iter (to prevent conflicts of already existing files)") flag.Parse() originalExtensions := make(map[string]string) var mapMutex sync.RWMutex var wg sync.WaitGroup extensionRegex := regexp.MustCompile(`\.[a-zA-Z0-9]+$`) if *recreate { log.Printf("Recreating all files first") for _, file := range flag.Args() { wg.Add(1) go func(file string) { defer wg.Done() _, err := os.Stat(file) if os.IsNotExist(err) { log.Printf("File %s does not exist", file) return } res := extensionRegex.FindAllString(file, -1) if len(res) == 0 { log.Printf("No extension found for file %s", file) return } dir := path.Dir(file) extension := res[0] bckpFile := fmt.Sprintf("%s/%s.bak", dir, file) _, err = os.Stat(bckpFile) if !os.IsNotExist(err) { log.Printf("File %s already exists", bckpFile) return } log.Printf("%s -> %s", file, bckpFile) err = os.Rename(file, bckpFile) if err != nil { log.Printf("Error renaming file %s to %s: %s", file, bckpFile, err) } mapMutex.Lock() originalExtensions[bckpFile] = extension mapMutex.Unlock() }(file) } } wg.Wait() wg = sync.WaitGroup{} for _, file := range flag.Args() { wg.Add(1) go func(file string) { defer wg.Done() if *recreate { file = file + ".bak" } info, err := os.Stat(file) if os.IsNotExist(err) { log.Printf("File %s does not exist", file) return } if info.IsDir() { log.Printf("File %s is a directory", file) return } modtime := info.ModTime() modtimeString := modtime.Local().Format("2006-01-02T15-04-05") newFile := modtimeString bakless := strings.TrimRight(file, ".bak") res := extensionRegex.FindAllString(bakless, -1) if len(res) == 0 { log.Printf("No extension found for file %s", file) return } extension := res[0] mapMutex.RLock() prevExtension, ok := originalExtensions[file] mapMutex.RUnlock() if ok { extension = prevExtension } dir := path.Dir(file) newFile = fmt.Sprintf("%s/%s%s", dir, newFile, extension) newFile = path.Clean(newFile) newFile = strings.TrimRight(newFile, ".bak") _, err = os.Stat(newFile) if os.IsExist(err) { log.Printf("File %s already exists", newFile) return } else if !os.IsNotExist(err) { log.Printf("An unexpected error occurred: %v", err) return } log.Printf("%s -> %s", file, newFile) err = os.Rename(file, newFile) if err != nil { log.Printf("Error renaming file %s to %s: %s", file, newFile, err) return } }(file) } wg.Wait() }