Do you want to process a path that contains wildcards and delete found folders/files? As far as I know, there are currently no methods that allow wildcards to be used in any part of the path. So I wrote my method:
/// <summary> /// Parse path that may contain wildcards /// </summary> /// <param name="pathWithWildcards">The pattern by which we are looking for files/folders</param> /// <param name="isFolder">Looking for folders or files?</param> /// <returns>List of paths that match the specified pattern</returns> public static List<string> ParsePath(string pathWithWildcards, bool isFolder = false) { if (string.IsNullOrEmpty(pathWithWildcards)) return new List<string>(0); if (!pathWithWildcards.Any(x => x == '*' || x == '?')) return new List<string> { pathWithWildcards }; if (!pathWithWildcards.Contains(':')) { string[] pathParts = pathWithWildcards.Split('\\'); pathParts[0] = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, pathParts[0]).TrimEnd('\\'); pathWithWildcards = string.Join("\\", pathParts); } List<string> paths = new List<string>(); List<string> patterns = new List<string> { pathWithWildcards }; while (patterns.Count > 0) { string[] pathParts = patterns[0].Split('\\'); for (int i = 0; i < pathParts.Length; i++) { if (!pathParts[i].Any(x => x == '*' || x == '?')) continue; string firstPart = string.Join("\\", pathParts.Take(i)) + "\\"; string lastPart = pathParts.Length > i + 1 ? string.Join("\\", pathParts.Skip(i + 1)) : string.Empty; if (!Directory.Exists(firstPart)) { patterns.RemoveAt(0); break; } bool isFinalAndFile = lastPart.Length == 0 && !isFolder; string[] search = isFinalAndFile ? Directory.GetFiles(firstPart, pathParts[i]) : Directory.GetDirectories(firstPart, pathParts[i]); if (lastPart.Length > 0) search = search.Select(x => Path.Combine(x, lastPart)).ToArray(); IEnumerable<string> withPattern = search.Where(x => x.Any(y => y == '*' || y == '?')); patterns.AddRange(withPattern); paths.AddRange(search.Except(withPattern).Where(x => isFinalAndFile ? File.Exists(x) : Directory.Exists(x))); patterns.RemoveAt(0); break; } } return paths; }
Usage example:
Stopwatch sw = new Stopwatch(); string path1 = "C:\\Users\\*\\AppData\\*\\Ad?be\\Color"; sw.Start(); List<string> test1 = ParsePath(path1, true); Console.WriteLine($"Found: {test1.Count} folder(s)\nElapsed time: {sw.ElapsedMilliseconds} ms\nList:"); test1.ForEach(f => Console.WriteLine(f)); string path2 = "C:\\Users\\*\\AppData\\*\\Ad?be\\Color\\ACE*.lst"; sw.Restart(); List<string> test2 = ParsePath(path2); Console.WriteLine($"Found: {test2.Count} file(s)\nElapsed time: {sw.ElapsedMilliseconds} ms\nList:"); test2.ForEach(f => Console.WriteLine(f)); string path3 = "*\\test (*).txt"; sw.Restart(); List<string> test3 = ParsePath(path3); Console.WriteLine($"Found: {test3.Count} file(s)\nElapsed time: {sw.ElapsedMilliseconds} ms\n"); // Output: // Found: 2 folder(s) // Elapsed time: 13 ms // List: // C:\Users\Andrew\AppData\Local\Adobe\Color // C:\Users\Andrew\AppData\Roaming\Adobe\Color // Found: 2 file(s) // Elapsed time: 2 ms // List: // C:\Users\Andrew\AppData\Local\Adobe\Color\ACECache11.lst // C:\Users\Andrew\AppData\Roaming\Adobe\Color\ACEConfigCache2.lst // Found: 2000 file(s) // Elapsed time: 105 ms
Found folders/files can be deleted immediately, but I advise you to do this only if you are completely sure of your pattern. Otherwise, you may accidentally delete important data
ParsePath("Test folder\\*\\*.txt").ForEach(f => File.Delete(f)); ParsePath("Test folder\\*", true).ForEach(f => Directory.Delete(f));
*in path.