將目錄下檔案依副檔名和父資料夾進行分組並統計重覆次數
前一篇文章可以取得目錄下,符合特定規則的檔案清單,但是我手邊的需求,還需要依副檔名分類,且統計「父資料夾\檔案名稱」重覆出現的次數,也就是如果是下述結構:
DirAAA\ \Shared \leo.asmx \Test \rose.ascx \leo.asmx DirBBB\ \Shared \leo.asmx \Test \rose.ascx \wang.asmx
預期的結果必須是:
asmx: Shared\leo.asmx -> 2 次 Test\leos.asmx -> 1 次 Test\wang.asmx -> 1 次 ascx: Test\rose.ascx -> 2 次
所以,一樣先看 Code 吧(請注意,以下程式使用 LINQPad 的 C# Program 模式執行):
void Main()
{
string[] files = GetDirectoryFiles(@"d:\MyDocs\Visual Studio 2008\");
var result = GetResultApplyDistinct(files);
result.Dump();
}
class FileGroupObject{
public string GroupKey { get; set; }
public int Count { get; set; }
}
IEnumerable<IGrouping<string, FileGroupObject>> GetResultApplyDistinct(string[] files)
{
var reg = new Regex(@"^.+\\(?<FolderAndFile>\w+\\.+$)");
var folderStartMatch = new Regex(@"^[a-zA-Z]+.*$");
var queryDistinct = files.GroupBy (f => reg.Match(f).Result("${FolderAndFile}"))
.Where(f => folderStartMatch.IsMatch(f.Key))
.GroupBy (f => Path.GetExtension(f.Key).ToLower(),
x => new FileGroupObject() {GroupKey = x.Key, Count = x.Count()});
return queryDistinct;
}
string[] GetDirectoryFiles(string path)
{
string[] files = Directory.EnumerateFiles(path, ".", SearchOption.AllDirectories)
.Where (f => { string ext = Path.GetExtension(f).ToLower();
if (".ascx".Equals(ext) || ".asmx".Equals(ext) )
{
return true;
}
return false;})
.OrderBy (f => Path.GetExtension(f).ToLower())
.ToArray();
return files;
}
輸出結果部分截圖:
程式碼流程說明:
- 我們先透過前一篇文章說明的 GetDirectoryFiles 方法,取得檔案清單。
- 定義一個 FileGroupObject 用來承接之後 LINQ 查詢的結果。
- 呼叫 GetResultApplyDistinct() 方法,傳入檔案清單,即可取得結果。
GetResultApplyDistinct() 方法是這次功能的核心,重點就是裡面的 正規式和 LINQ,茲說明如下:
var reg = new Regex(@"^.+\\(?<FolderAndFile>\w+\\.+$)");
這個正規式,目的是取出「父資料夾\檔案名稱」這個值。
var folderStartMatch = new Regex(@"^[a-zA-Z]+.*$");
這個正規式目的是排除非英文字器打頭的父資料夾,原因是有些「測試\test.asmx」這類程式,要排除在本次統計資料中。
var queryDistinct = files.GroupBy (f => reg.Match(f).Result("${FolderAndFile}"))
.Where(f => folderStartMatch.IsMatch(f.Key))
.GroupBy (f => Path.GetExtension(f.Key).ToLower(),
x => new FileGroupObject() {GroupKey = x.Key, Count = x.Count()});
- 首先我們依檔案所屬的父資料夾做群組,透過 reg.Match(f).Result("${folder}") 取得父資料夾。
- 透過 folderStartMatch.IsMatch(f.Key) 排除非英文字起頭的父資料夾之檔案。
- 再依檔案的副檔名做群組,並重新輸出 FileGroupObject 清單。因為已經先用「父資料夾\檔案名稱」做過一次分組,所以現在透過副檔名再分組時,只要直接取得 Count,就可以列出重覆的檔案數。
--------
沒什麼特別的~
不過是一些筆記而已