我正在寻找一个解决方案来比较2个.csv文件并比较结果。
第一个.csv文件是基于客户端名称的每月备份大小(KB(。第二个.csv文件是基于客户端名称的下一个月备份大小(KB(。
它列出了A列中的所有客户端名称。B列具有相应的客户端策略名称和最后一列备份大小(KB((即-487402463(。
如果客户端大小(1638838488-1238838488=0.37 TB(之间的差异大于0.10 TB,则结果将以TB大小显示到csv文件中,如下所示。
此外,客户端可以关联多个策略名称。
我的问题是:我也想补充一些内容。有时它可能是重复的客户端和策略名称,如hostnameXX、Company_policy_XXX或区分大小写的hostnameXX、Company _policy_XXX。另外,假设在CSV2中不存在hostnameYY,Company_PolicyXXX,41806794,那么我想显示为负数,如下所示。
我使用了Join Object模块。
示例CSVFile1.csv
Client Name,Policy Name,KB Size
hostname1,Company_Policy,487402463
hostname2,Company_Policy,227850336
hostname3,Company_Policy_11,8360960
hostname4,Company_Policy_11,1238838488
hostname1,Company_Policy_55,521423110
hostname10,Company_Policy,28508975
hostname3,Company_Policy_66,295925
hostname5,Company_Policy_22,82001824
hostname2,Company_Policy_33,26176885
hostnameXX,Company_Policy_XXX,0
hostnameXX,Company_Policy_XXX,41806794
hostnameYY,Company_Policy_XXX,41806794
示例CSVFile2.csv
Client Name,Policy Name,KB Size
hostname1,Company_Policy,487402555
hostname2,Company_Policy,227850666
hostname3,Company_Policy_11,8361200
hostname4,Company_Policy_11,1638838488
hostname1,Company_Policy_55,621423110
hostname10,Company_Policy,28908975
hostname3,Company_Policy_66,295928
hostname5,Company_Policy_22,92001824
hostname2,Company_Policy_33,36176885
hostname22,Company_Policy,291768854
hostname23,Company_Policy,291768854
期望输出:
Client Name,Policy Name,TB Size
hostname4,Company_Policy_11,0.37
hostname22,Company_Policy,0.27
hostname23,Company_Policy,0.27
hostnameYY,Company_Policy_XXX,-0.03
hostnameXX,Company_Policy_XXX,-0.04
使用此Join-Object cmdlet(另请参阅:将两个表连接为一个表的最佳方法是什么?(:
$CSV2 | FullJoin $CSV1 `
-On 'Client Name','Policy Name' `
-Property 'Client Name',
'Policy Name',
@{'TB Size' = {[math]::Round(($Left.'KB Size' - $Right.'KB Size') * 1KB / 1TB, 2)}} |
Where-Object {[math]::Abs($_.'TB Size') -gt 0.01}
结果:
Client Name Policy Name TB Size
----------- ----------- -------
hostname4 Company_Policy_11 -0.37
hostname1 Company_Policy_55 -0.09
hostnameXX Company_Policy_XXX 0.04
hostnameYY Company_Policy_XXX 0.04
hostname22 Company_Policy -0.27
hostname23 Company_Policy -0.27
更新2019-11-24
改进的-Where
参数现在也将应用于外部联接
您现在可以对这些类型的查询使用-Where
参数而不是Where-Object
cmdlet,例如:
$Actual = $CSV2 | FullJoin $CSV1 `
-On 'Client Name','Policy Name' `
-Property 'Client Name',
'Policy Name',
@{'TB Size' = {[math]::Round(($Left.'KB Size' - $Right.'KB Size') / 1GB, 2)}} `
-Where {[math]::Abs($Left.'KB Size' - $Right.'KB Size') -gt 100MB}
使用-Where
参数的优点是,由于根本不需要创建某些输出对象,因此性能略有提高。
注意1:-Where
参数适用于分别表示每个$LeftInput
和$RightInput
对象的$Left
和$Right
对象,而不适用于输出对象。换句话说,您不能在本例的-Where
表达式中使用例如计算的TB Size
属性
注意2:$Right
对象始终存在于左联接或全联接中,即使没有关系。如果没有关系,则$Right
对象的所有属性都将设置为$Null
。这同样适用于右联接或完全联接中的$Left
对象
我从未使用过Join Object模块,所以我使用标准cmdlet编写它。
$data1 = Import-Csv "CSVFile1.csv"
$data1 | ForEach-Object { $_."KB Size" = -1 * $_."KB Size" } # Convert to negative value
$data2 = Import-Csv "CSVFile2.csv"
@($data2; $data1) | Group-Object "Client Name","Policy Name" | ForEach-Object {
$size = [Math]::Round(($_.Group | Measure-Object "KB Size" -Sum).Sum * 1KB / 1TB, 2)
if ($size -ge 0 -and $size -lt 0.1) { return }
[pscustomobject]@{
"Client Name" = $_.Group[0]."Client Name"
"Policy Name" = $_.Group[0]."Policy Name"
"TB Size" = $size
}
}