package main import ( "bufio" "flag" "fmt" "log" "os" "path/filepath" "regexp" "strings" "time" ) type FileInfo struct { FilePath string FileName string FileSize int64 FileTime time.Time } var ( diffYear int = 0 bkupPath string = "" autoBkup bool = false exclude bool = false aodType string = "" aodPath string = "" modPath string = "" skipFile string = "" aodList = make([]string, 0) criList = make([]string, 0) moduleList = make([]string, 0) skipList = make([]string, 0) bkupList = make([]string, 0) uniqueCriList = make([]string, 0) uniqueModuleList = make([]string, 0) needlessModuleList = make([]string, 0) needlessModuleInfo = make([]string, 0) missingModuleList = make([]string, 0) errAOD = make([]string, 0) errCRI = make([]string, 0) aodInfoList []FileInfo moduleInfoList []FileInfo ) var regFilter = `.*` var regLNB = `(?i)\S{10,}\.[0-9]{3}` var regTNB = `(?i)SSW\S{7}\.SSW\S{7}` var regSBID = `(?i)\S{8,}\.DAT` func init() { flag.BoolVar(&exclude, "x", false, "Exclude Mode") flag.BoolVar(&autoBkup, "y", false, "Auto Backup") flag.IntVar(&diffYear, "d", 6, "Differ Year Of File Time to Backup") flag.StringVar(&aodPath, "a", `D:\Vol1\PDLINE\PLANT1\PRELOAD\AOD`, "Path Of AODs") flag.StringVar(&modPath, "m", `D:\COMMON`, "Path Of Modules") flag.StringVar(&bkupPath, "b", `D:\COMMON_BKUP`, "Path Of Backup") flag.StringVar(&aodType, "t", "*", "Type Of AODs, LNB/TNB/SBID/*") flag.StringVar(&skipFile, "s", "./SkipList.txt", "Text File Of Skip Modules") flag.Parse() } func main() { log.SetOutput(os.Stdout) log.Printf("[MSG] Commandline: %v\r\n", os.Args) bkupList = append(bkupList, fmt.Sprintf("### Commandline: %v", os.Args)) _, err := os.Stat(aodPath) if err != nil { log.Printf("[ERR] Path Of AODs Not Exists.\r\n") os.Exit(1) } _, err = os.Stat(modPath) if err != nil { log.Printf("[ERR] Path Of Modules Not Exists.\r\n") os.Exit(1) } if skipFile != "" { obj, err := os.Open(skipFile) if err == nil { buf := bufio.NewScanner(obj) for buf.Scan() { if buf.Err() != nil { break } skipList = append(skipList, strings.TrimSpace(buf.Text())) } } } log.Printf("[MSG] Skip Modules: %d\r\n", len(skipList)) log.Printf("[MSG] Summary Loacal AODs ...\r\n") aodInfoList, err = _SummaryAODs(aodPath, aodType) if err != nil { log.Printf("[ERR] Get AOD List Failed: %s\r\n", err.Error()) os.Exit(1) } log.Printf("[MSG] Total Local AODs: %d\r\n", len(aodInfoList)) _WriteFileFromStringSlice("./AOD.txt", aodList) log.Printf("[MSG] Summary Local Modules ...\r\n") moduleInfoList, err = _SummaryModules(modPath) if err != nil { log.Printf("[ERR] Get Module List Failed: %s\r\n", err.Error()) os.Exit(1) } log.Printf("[MSG] Total Local Modules: %d\r\n", len(moduleInfoList)) regCRI, err := regexp.Compile(`(?i).*File=(.{1,}.CRI)`) if err != nil { log.Printf("[ERR] RegExp - CRI Compile Error: %s\r\n", err.Error()) os.Exit(1) } log.Printf("[MSG] Summary CRIs From AODs ...\r\n") for _, aod := range aodList { rdr, err := os.Open(aod) if err != nil { errAOD = append(errAOD, aod) continue } buf := bufio.NewScanner(rdr) for buf.Scan() { if buf.Err() != nil { break } rst := regCRI.FindStringSubmatch(buf.Text()) if len(rst) != 2 { continue } criList = append(criList, strings.TrimSpace(rst[1])) } } log.Printf("[MSG] Total CRIs From AODs: %d\r\n", len(criList)) uniqueCriList = _RemoveDuplicateElementOfSlice(criList) log.Printf("[MSG] Unique CRIs From AODs: %d\r\n", len(uniqueCriList)) regModuleName, err := regexp.Compile(`(?i)(ModuleName[0-9]{0,}|ModuleThis[0-9]{0,})=(.{1,})`) if err != nil { log.Printf("[ERR] RegExp - ModuleName Compile Error: %s\r\n", err.Error()) os.Exit(1) } log.Printf("[MSG] Summary Modules From CRIs ...\r\n") for _, cri := range uniqueCriList { rdr, err := os.Open(modPath + "\\" + cri) if err != nil { errCRI = append(errCRI, modPath+"\\"+cri) } buf := bufio.NewScanner(rdr) for buf.Scan() { if buf.Err() != nil { break } rst := regModuleName.FindStringSubmatch(buf.Text()) if len(rst) != 3 { continue } moduleList = append(moduleList, strings.TrimSpace(rst[2])) } } log.Printf("[MSG] Total Modules From CRIs: %d\r\n", len(moduleList)) uniqueModuleList = _RemoveDuplicateElementOfSlice(moduleList) log.Printf("[MSG] Unique Modules From CRIs: %d\r\n", len(uniqueModuleList)) _WriteFileFromStringSlice("./NeededModules.txt", uniqueModuleList) log.Printf("[MSG] Checking Missing Modules ...\r\n") for _, m := range uniqueModuleList { exist := false for _, l := range moduleInfoList { if strings.EqualFold(m, l.FileName) { exist = true break } } if !exist { missingModuleList = append(missingModuleList, m) } } log.Printf("[MSG] Checking Needless Modules ...\r\n") for _, l := range moduleInfoList { needless := true for _, m := range uniqueModuleList { if strings.EqualFold(l.FileName, m) { needless = false break } } if needless { needlessModuleList = append(needlessModuleList, l.FileName) needlessModuleInfo = append(needlessModuleInfo, l.FileName+"\t"+l.FileTime.Format("2006-01-02 15:04:05")) } } log.Printf("***** Error AODs: %d\r\n", len(errAOD)) _WriteFileFromStringSlice("./errAOD.txt", errAOD) log.Printf("***** Error CRIs: %d\r\n", len(errCRI)) _WriteFileFromStringSlice("./errCRI.txt", errCRI) log.Printf("##### Missing Modules: %d\r\n", len(missingModuleList)) _WriteFileFromStringSlice("./MissingModules.txt", missingModuleList) log.Printf("##### Needless Modules: %d\r\n", len(needlessModuleList)) _WriteFileFromStringSlice("./NeedlessModules.txt", needlessModuleInfo) if autoBkup { log.Printf("[MSG] Starting Backup Modules Older Than %d Years ...\r\n", diffYear) _, err := os.Stat(bkupPath) if err != nil { err = os.MkdirAll(bkupPath, os.ModePerm) if err != nil { log.Printf("[ERR] Create Backup Directory Failed.\r\n") os.Exit(1) } } ttl := 0 LOOP: for _, n := range needlessModuleList { for _, s := range skipList { if s == n { log.Printf("[MSG] Skip Backup Module: %s\r\n", s) continue LOOP } } for _, m := range moduleInfoList { if m.FileName == n { if m.FileTime.AddDate(diffYear, 0, 0).Before(time.Now()) { err := os.Rename(m.FilePath, bkupPath+"\\"+m.FileName) if err != nil { log.Printf("[ERR] FileName: %s;\tErrMsg: %s\r\n", m.FileName, err.Error()) break } bkupList = append(bkupList, m.FileName+"\t"+m.FileTime.Format("2006-01-02 15:04:05")) log.Printf("[MSG] FileName: %s;\tFileTime: %s\r\n", m.FileName, m.FileTime.Format("2006-01-02 15:04:05")) ttl += 1 break } } } } _WriteFileFromStringSlice("./Backup_"+time.Now().Format("2006-01-02_15-04-05")+".txt", bkupList) log.Printf("[MSG] Total Backed Up Modules: %d\r\n", ttl) } } func _SummaryAODs(basePath, filter string) ([]FileInfo, error) { var err error sortInfoList := make([]FileInfo, 0) fileInfoList := make([]FileInfo, 0) err = filepath.Walk(basePath, func(path string, info os.FileInfo, err error) error { if !info.IsDir() { fi := new(FileInfo) fi.FilePath = path fi.FileName = info.Name() fi.FileSize = info.Size() fi.FileTime = info.ModTime() //.Format("2006-01-02 15:04:05") fileInfoList = append(fileInfoList, *fi) aodList = append(aodList, fi.FilePath) } return nil }) if err != nil { log.Printf("[ERR] Get File List Failed: %s\r\n", err.Error()) return nil, err } switch filter { case "LNB": regFilter = regLNB case "TNB": regFilter = regTNB case "SBID": regFilter = regSBID default: return fileInfoList, nil } for _, i := range fileInfoList { reg := regexp.MustCompile(regFilter) rst := reg.FindStringSubmatch(i.FileName) if exclude { if len(rst) == 1 { continue } sortInfoList = append(sortInfoList, i) } if !exclude { if len(rst) != 1 { continue } sortInfoList = append(sortInfoList, i) } } return sortInfoList, nil } func _SummaryModules(basePath string) ([]FileInfo, error) { var err error fileInfoList := make([]FileInfo, 0) err = filepath.Walk(basePath, func(path string, info os.FileInfo, err error) error { if !info.IsDir() { fi := new(FileInfo) fi.FilePath = path fi.FileName = info.Name() fi.FileSize = info.Size() fi.FileTime = info.ModTime() //.Format("2006-01-02 15:04:05") if path == basePath+"\\"+info.Name() { fileInfoList = append(fileInfoList, *fi) } } return nil }) if err != nil { log.Printf("[ERR] Get File List Failed: %s\r\n", err.Error()) return nil, err } return fileInfoList, nil } func _RemoveDuplicateElementOfSlice(src []string) []string { dst := make([]string, 0, len(src)) tmp := map[string]struct{}{} for _, s := range src { if _, ok := tmp[s]; !ok { tmp[s] = struct{}{} dst = append(dst, s) } } return dst } func _WriteFileFromStringSlice(fileName string, dataSlice []string) { obj, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666) if err != nil { log.Printf("[ERR] Open File Error: %s\r\n", err.Error()) return } defer obj.Close() var builder strings.Builder for _, s := range dataSlice { builder.WriteString(s + "\r\n") } _, err = obj.WriteString(builder.String()) if err != nil { log.Printf("[ERR] Write File Error: %s\r\n", err.Error()) return } }