package main import ( "fmt" "os" "path/filepath" "regexp" "slices" "strconv" "strings" ) type Pair struct { originFull string newName string newFull string skip bool } var ( exts = []string{ ".jpg", ".jpeg", ".jfif", ".png", ".gif", ".webp", ".mp4", ".MP4", ".webm", } renameSlice []Pair pattern, _ = regexp.Compile("^\\d+(-\\d)?$") // 123456789, 123456789-1 ) func generateName(baseName string) string { counter := 1 name := baseName loop: for { for _, pair := range renameSlice { if pair.newName == name { name = fmt.Sprintf("%s-%d", baseName, counter) counter++ continue loop } } break } return name } func main() { entries, err := os.ReadDir(".") if err != nil { panic(err) } renameSlice = make([]Pair, 0) for _, entry := range entries { if entry.IsDir() { continue } ext := filepath.Ext(entry.Name()) extL := strings.ToLower(ext) if !slices.Contains(exts, extL) { continue } if pattern.MatchString(strings.TrimSuffix(entry.Name(), ext)) { renameSlice = append(renameSlice, Pair{ originFull: entry.Name(), skip: true}) continue } info, err := entry.Info() if err != nil { panic(err) } newName := generateName(strconv.FormatInt(info.ModTime().Unix(), 10)) renameSlice = append(renameSlice, Pair{ originFull: entry.Name(), newName: newName, newFull: newName + extL}) } counter := 0 for i, pair := range renameSlice { if pair.skip || pair.originFull == pair.newFull { continue } fmt.Printf("%d. %s --> %s\n", i+1, pair.originFull, pair.newFull) err := os.Rename(pair.originFull, pair.newFull) if err != nil { panic(err) } counter++ } fmt.Printf("Total: %d\n", len(renameSlice)) fmt.Printf("Renamed: %d\n", counter) }