You can use this Linq query with Enumerable.GroupBy , which should work (now tested):
var allFiles = Directory.EnumerateFiles(sourceDir, "*.dwg") .Select(path => new { Path = path, FileName = Path.GetFileName(path), FileNameWithoutExtension = Path.GetFileNameWithoutExtension(path), VersionStartIndex = Path.GetFileNameWithoutExtension(path).LastIndexOf('_') }) .Select(x => new { x.Path, x.FileName, IsVersionFile = x.VersionStartIndex != -1, Version = x.VersionStartIndex == -1 ? new Nullable<int>() : x.FileNameWithoutExtension.Substring(x.VersionStartIndex + 1).TryGetInt(), NameWithoutVersion = x.VersionStartIndex == -1 ? x.FileName : x.FileName.Substring(0, x.VersionStartIndex) }) .OrderByDescending(x => x.Version) .GroupBy(x => x.NameWithoutVersion) .Select(g => g.First()); foreach (var file in allFiles) { string oldPath = Path.Combine(sourceDir, file.FileName); string newPath; if (file.IsVersionFile && file.Version.HasValue) newPath = Path.Combine(versionPath, file.FileName); else newPath = Path.Combine(noVersionPath, file.FileName); File.Copy(oldPath, newPath, true); }
Here is the extension method that I use to determine if a string available to int :
public static int? TryGetInt(this string item) { int i; bool success = int.TryParse(item, out i); return success ? (int?)i : (int?)null; }
Please note that I do not use only regular expressions, but only string methods.
source share