我一直在嘗試創建一個小程式來比較兩個字串集合并輸出collection1和collection2之間不同或缺失的任何專案。
據我所知,LINQ 的 .Except 方法應該能提供我想要的結果,但它似乎達不到要求。
我要比較的檔案是使用 ICACLS 生成的 ACL 檔案,通過從 cmd 運行以下命令來保存給定目錄及其子目錄的所有權限:
icacls c:\TestHash /save c:\aclFile.txt /t
我在一個目錄上運行此命令兩次以生成兩個要確保匹配的 icacls 檔案,如果它們不匹配,那么我想輸出它們不匹配的位置。
這是一些嘗試比較這些專案的示例代碼
//Load in user permissions files
var list1 = File.ReadAllLines(dbFilePath1, Encoding.Unicode);
var list2 = File.ReadAllLines(dbFilePath2, Encoding.Unicode);
加載專案后,我將運行 .Except 命令
//Identify all differences between the two collections and output to new collection
var list3 = list1.Except(list2);
var list4 = list2.Except(list1);
但是,下面是檔案 1 中的 10 條記錄的示例,其中我從檔案 2 中洗掉了一條權限記錄,但是 .Except 沒有識別出它缺少該專案
第一個檔案:
TestHash
D:AI(A;OICIID;FA;;;BC)(A;OICIID;FD;;;SY)(A;OICIID;0x1200a9;;;BU)(A;ID;0x1307by;;;AU)(A;OICIIOID;SDGXGWGR;;;AU)
TestHash\testFile1.csv
D:AI(A;ID;FA;;;BD)(A;ID;FR;;;SY)(A;ID;0x1200a9;;;BU)(A;ID;0x1307by;;;AU)
TestHash\testFile2.csv
D:AI(A;ID;FA;;;BD)(A;ID;FR;;;SY)(A;ID;0x1200a9;;;BU)(A;ID;0x1307by;;;AU)
TestHash\testFile3.csv
D:AI(A;ID;FA;;;BD)(A;ID;FR;;;SY)(A;ID;0x1200a9;;;BU)(A;ID;0x1307by;;;AU)
TestHash\testFile4.csv
D:AI(A;ID;FA;;;BD)(A;ID;FR;;;SY)(A;ID;0x1200a9;;;BU)(A;ID;0x1307by;;;AU)
第二個檔案:
TestHash
D:AI(A;OICIID;FA;;;BC)(A;OICIID;FD;;;SY)(A;OICIID;0x1200a9;;;BU)(A;ID;0x1307by;;;AU)(A;OICIIOID;SDGXGWGR;;;AU)
TestHash\testFile1.csv
D:AI(A;ID;FA;;;BD)(A;ID;FR;;;SY)(A;ID;0x1200a9;;;BU)(A;ID;0x1307by;;;AU)
TestHash\testFile2.csv
D:AI(A;ID;FA;;;BD)(A;ID;FR;;;SY)(A;ID;0x1200a9;;;BU)(A;ID;0x1307by;;;AU)
TestHash\testFile3.csv
TestHash\testFile4.csv
D:AI(A;ID;FA;;;BD)(A;ID;FR;;;SY)(A;ID;0x1200a9;;;BU)(A;ID;0x1307by;;;AU)
如上所述,第二個檔案缺少一個權限記錄,但 .Except 無法識別這一點,集合被作為字串列舉處理,并且據我所知,默認相等比較器應該能夠檢測到這種差異,我'我知道您可以使用自定義比較器覆寫它,但我不確定對此的實作是什么。
另一個注意事項是,這似乎只會引發任何權限字串本身的問題,.Except 似乎確實能夠確定任何丟失的字串,當它是檔案夾/檔案名之一時,所以我認為它可能會感到困惑因為集合中有許多相同的權限字串,所以它可能認為它有一個匹配的專案,即使它沒有與特定檔案相關的特定記錄。
我希望這將需要某種自定義覆寫,但我不確定這個實作會是什么。
任何想法將不勝感激,感謝您花時間閱讀本文。
uj5u.com熱心網友回復:
我不確定我的假設是否正確,但看起來生成的檔案格式是每個目錄條目兩行,第一行是檔案的完整路徑,因此必須是唯一的。
如果這是正確的,那么第二個串列不能包含該行TestHash\testFile3.csv。
如果是這樣,那么您可以使用權限對目錄條目進行分組,然后使用 except 檢查差異。
為此,我首先為每行添加一個行號,然后按每兩行分組,并創建一個匿名物件,其中包含每組中的第一個和第二個條目,
例如
var groupedList1 = list1
.Select((val , index) => new { val, index })
.GroupBy(g => g.index / 2)
.Select(r => r.ToArray())
.Select(r => new { DirectoryEntry = r[0].val , OldPermission = r[1].val , NewPermission = ""}) ;
因為 DirectoryEntry Name 是唯一的,所以我們知道分組串列中的每個條目都必須是唯一的,因此 except 運算子將根據您的需要進行操作。
或者你可以結合 groupedList1 和 groupedList2 像
var allEntries = groupedList1.Select(a=>a.DirectoryEntry).Union(
groupedList2.Select(a=>a.DirectoryEntry));
var combined = (from r in allEntries select new
{
DirectoryEntry = r ,
OldPermission = groupedList1.SingleOrDefault(a=>a.DirectoryEntry == r)?.Permission ,
NewPermission = groupedList2.SingleOrDefault(a=>a.DirectoryEntry == r)?.Permission
}
)
.Where(a=>a.OldPermission != a.NewPermission);
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/494201.html
