【问题标题】:Find directories at specific depth level with wildcard matching使用通配符匹配查找特定深度级别的目录
【发布时间】:2020-01-27 05:40:54
【问题描述】:

我有一个这样的目录结构:

A: -
   B1 - C11 - D111 
        C12 - D121
              D122
   B2 - C21
        C22
        C23
        C24
   B3 - C31

现在,只获取二级目录,在 PowerShell 中是直接的:

$LEVEL2 = get-childitem -Path 'A:\*\*'  | ?{ $_.PSIsContainer } 

这会给我:

C11, C12, C21, C22, C23, C24, C31

现在,我想在 c# 中执行此操作。有人可以帮忙吗?

【问题讨论】:

  • 这能回答你的问题吗? Resolving relative paths with wildcards in C#
  • 不,实际上我想要的是所有子目录的列表,而不是特定的文件类型。
  • 然后将Directory.GetFiles() 替换为Directory.GetDirectories() 并且不要在模式字符串中添加扩展名。
  • 链接的帖子假定该模式只是文件名的一部分,不回答这个问题。像Directory.EnumerateDirectories 这样具有模式匹配的IO 函数,它们将模式应用于名称而不是路径。这是这个问题,模式应该适用如果你想依赖这些函数,你首先需要从给定的模式中找到根,然后通过分割模式进行模式匹配,将模式分割为` and then for each level, use EnumerateDirectories`。跨度>
  • @VishwasJoshi 给定的 PowerShell 不会在二级目录中停止。它还返回第 3 级和更深的级别。您是否需要像我在答案中所做的那样进行模式匹配?您需要第 2 级或更深的级别还是应该停止在第 2 级?

标签: c# .net powershell


【解决方案1】:

假设您有 System.LinqSystem.IO 在范围内,最简单的方法是:

Directory.EnumerateDirectories("A:\\").SelectMany(d => Directory.EnumerateDirectories(d))

【讨论】:

    【解决方案2】:

    我使用了以下支持*通配符的方法。这是算法,它检查路径是否包含*,然后从*的左侧,获取最后一个\,并将\的左侧作为搜索的根。

    例如,以下搜索将返回c:\test下的所有二级深度目录:

    var result = GetDirectories("c:\test\*\*");
    

    函数如下:

    string[] GetDirectories(string path)
    {
        var root = path;
        if (root.IndexOf('*') > -1)
            root = root.Substring(0, root.IndexOf('*'));
        if (root.LastIndexOf('\\') > -1)
            root = root.Substring(0, root.LastIndexOf('\\'));
        var all = Directory.GetDirectories(root, @"*", SearchOption.AllDirectories);
        var pattern = $"^{Regex.Escape(path).Replace("\\*", "[^\\\\]*")}$";
        return all.Where(x => Regex.IsMatch(x, pattern, RegexOptions.IgnoreCase)).ToArray();
    }
    

    该函数需要一些异常处理,例如在解析的根不存在的情况下。但在我的测试中,它适用于以下示例:

    • "c:\test\*"c:\test\路径下的所有目录
    • "c:\test\a*"c:\test\路径下的所有a*目录
    • "c:\test\a*\b*"c:\test\a*路径下的所有b*目录
    • "c:\test\a*\b"c:\test\a*路径下的所有b目录
    • "c:\test\*\*"c:\test下的所有目录二级深度

    【讨论】:

    • 谢谢。我一直在寻找这种解决方案。谢谢。
    • 如果您不想将结果限制在模式指定的最后一级,只需在函数中使用".*"而不是"[^\\\\]*"
    【解决方案3】:
    class Program
    {
       //Result Variable
        public static List<string> finalRes = new List<string>();
       //Level at which you want 
        public static int reqLevel = 3;
    
        static void Main(string[] args)
        {
            try
            {
                var path = @"D:\Personal\";
                GetFolederNames(path, 0);
    
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
    
        }
    
        public static void GetFolederNames(string path, int level)
        {
    
            var subDirs = new List<string>();
            subDirs = Directory.GetDirectories(path).ToList();
            if (level == reqLevel)
            {
                finalRes.Add(path);
                return;
            }
            foreach (var dir in subDirs)
            {
                if(finalRes.Contains(dir))
                    continue;
    
                GetFolederNames(dir, level+1);
            }
    
        }
    }
    

    【讨论】:

    • 也许你正在回答another question。当前问题需要模式匹配。
    • @RezaAghaei 他没有特别提到使用模式匹配。据我所知,他只需要特定级别的目录。
    猜你喜欢
    • 2021-06-04
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    • 2013-10-26
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 2014-02-14
    相关资源
    最近更新 更多