使用PowerShell比较两个不同的csv文件



我正在寻找一个解决方案来比较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-Objectcmdlet,例如:

$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
}
}

相关内容

  • 没有找到相关文章

最新更新