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));