using Microsoft.Extensions.Logging; using System.Globalization; namespace File_Folder_Helper.ADO2025.PI7; internal static partial class Helper20250926 { internal static void RenameThenFindFirstAndLast(ILogger logger, List args) { logger.LogInformation(args[0]); logger.LogInformation(args[1]); logger.LogInformation(args[2]); logger.LogInformation(args[3]); logger.LogInformation(args[4]); logger.LogInformation(args[5]); Rename(logger, args); if (args.Count > 99) { FindFirstAndLast(logger, args); } } internal static void Rename(ILogger logger, List args) { string check; string[] files; string[] lines; string checkFile; DateTime lastDate; string[] segments; string[] segmentsB; DateTime firstDate; const char star = '*'; const char underscore = '_'; string dateFormat = args[4]; string destinationDirectory; FileInfo[] fileInfoCollection; int seconds = int.Parse(args[5]); string[] searchPatterns = args[2].Split('~'); string sourceDirectory = Path.GetFullPath(args[0]); string[] sourceDirectories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string searchPattern in searchPatterns) { if (!searchPattern.Contains(underscore) || !searchPattern.Contains(star)) { throw new Exception($"{nameof(searchPattern)} must contain {underscore} and {star}"); } segments = searchPattern.Split(star); segmentsB = segments[0].Split(underscore); foreach (string directory in sourceDirectories) { destinationDirectory = Path.Combine(directory, segmentsB[0], segmentsB[1]); if (!Directory.Exists(destinationDirectory)) { _ = Directory.CreateDirectory(destinationDirectory); } files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly); logger.LogInformation("With search pattern '{SearchPattern}' found {files} file(s)", searchPattern, files.Length); fileInfoCollection = files.Select(f => new FileInfo(f)).ToArray(); foreach (FileInfo fileInfo in fileInfoCollection.OrderBy(f => f.LastWriteTime)) { if (fileInfo.Length == 0 || fileInfo.LastWriteTime > DateTime.Now.AddMinutes(-1)) { logger.LogInformation("skipped '{FileInfo}'", fileInfo.FullName); continue; } lastDate = DateTime.MinValue; firstDate = DateTime.MinValue; try { lines = File.ReadAllLines(fileInfo.FullName); foreach (string line in lines) { if (line.Length < dateFormat.Length) { continue; } check = line[..dateFormat.Length]; if (!DateTime.TryParseExact(check, dateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime logDate)) { continue; } if (firstDate == DateTime.MinValue) { firstDate = logDate; } lastDate = logDate; } checkFile = Path.Combine(destinationDirectory, $"{firstDate:yyyy-MM-dd_HH-mm-ss}---{lastDate:yyyy-MM-dd_HH-mm-ss}.log"); if (checkFile == fileInfo.FullName || File.Exists(checkFile)) { logger.LogInformation("skipped '{CheckFile}'", checkFile); } else { logger.LogInformation("rename to '{CheckFile}'", checkFile); File.Move(fileInfo.FullName, checkFile); } } catch { logger.LogInformation("skipped '{FileInfo}'", fileInfo.FullName); } } } } } internal static void FindFirstAndLast(ILogger logger, List args) { string line; string check; string[] files; string[] lines; DateTime lastDate; TimeSpan timeSpan; string[] segments; string[] segmentsB; DateTime firstDate; const char star = '*'; const char underscore = '_'; string dateFormat = args[4]; string destinationDirectory; FileInfo[] fileInfoCollection; string searchString = args[3]; int seconds = int.Parse(args[5]); string[] searchPatterns = args[2].Split('~'); string sourceDirectory = Path.GetFullPath(args[0]); string[] sourceDirectories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string searchPattern in searchPatterns) { if (!searchPattern.Contains(underscore) || !searchPattern.Contains(star)) { throw new Exception($"{nameof(searchPattern)} must contain {underscore} and {star}"); } segments = searchPattern.Split(star); segmentsB = segments[0].Split(underscore); foreach (string directory in sourceDirectories) { destinationDirectory = Path.Combine(directory, segmentsB[0], segmentsB[1]); if (!Directory.Exists(destinationDirectory)) { _ = Directory.CreateDirectory(destinationDirectory); } files = Directory.GetFiles(destinationDirectory, $"*{segments[^1]}", SearchOption.TopDirectoryOnly); logger.LogInformation("With search pattern '{SearchPattern}' found {files} file(s)", searchPattern, files.Length); fileInfoCollection = files.Select(f => new FileInfo(f)).ToArray(); foreach (FileInfo fileInfo in fileInfoCollection.OrderBy(f => f.LastWriteTime)) { if (fileInfo.Length == 0 || fileInfo.LastWriteTime > DateTime.Now.AddMinutes(-1)) { logger.LogInformation("skipped '{FileInfo}'", fileInfo.FullName); continue; } lastDate = DateTime.MinValue; firstDate = DateTime.MinValue; try { lines = File.ReadAllLines(fileInfo.FullName); for (int i = 0; i < lines.Length; i++) { line = lines[i]; if (!line.Contains(searchString) || lines[i - 1].Length < dateFormat.Length) { continue; } check = lines[i - 1][..dateFormat.Length]; if (!DateTime.TryParseExact(check, dateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime logDate)) { continue; } timeSpan = logDate - lastDate; if (firstDate == DateTime.MinValue || timeSpan.TotalSeconds > seconds) { firstDate = logDate; } lastDate = logDate; } logger.LogInformation("include"); } catch { logger.LogInformation("skipped '{FileInfo}'", fileInfo.FullName); } } } } } }