【问题标题】:Compare two different csv files using PowerShell使用 PowerShell 比较两个不同的 csv 文件
【发布时间】:2019-11-14 05:46:36
【问题描述】:

我正在寻找一种解决方案来比较 2 个 .csv 文件并比较结果。

第一个 .csv 文件是基于客户端名称的每月备份大小(以 KB 为单位)。第二个 .csv 文件是基于客户端名称的下个月备份大小(以 KB 为单位)。

它在 A 列中列出了所有客户端名称。B 列具有客户端的相应策略名称和最后一列备份大小(以 KB 为单位)(即 - 487402463)。

如果客户端大小(1638838488 - 1238838488 = 0.37 in TB)之间的差异大于 0.10 TB,则结果将以 TB 大小输出到如下所示的 csv 文件中。

另外,一个客户端可能关联多个策略名称。

我的问题是:我也想添加一些东西。有时它可能是重复的客户端和策略名称,例如 hostnameXX,Company_Policy_XXX 或区分大小写的 HOSTNAMEXX,Company_Policy_XXX。 另外,假设 CSV2 中不存在 hostnameYY,Company_Policy_XXX,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

【问题讨论】:

    标签: powershell compare export-to-csv


    【解决方案1】:

    使用此Join-Object cmdlet(另请参阅:what's the best way to join two tables into one?):

    $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 参数适用于 $Left$Right 对象,它们分别代表 $LeftInput$RightInput 对象和 not 输出对象。换句话说,您不能使用例如此示例的 -Where 表达式中计算的 TB Size 属性。

    注意 2$Right 对象总是存在于左连接或完全连接中,即使没有关系。如果没有关系,$Right 对象的所有属性都将设置为$Null。这同样适用于右连接或全连接中的$Left 对象。

    【讨论】:

    • 谢谢 但是我怎样才能将我的脚本集成到您的解决方案中?
    • ili101 的脚本只是一个不同的 cmdlet/解决方案。我的版本的安装非常简单:从powershellgallery.com/packages/Join 下载脚本。只需dotsource 脚本如:. .\Join.ps1 调用它并运行如上所示的命令...
    • 好的,我知道了。另外,我需要导出为 CSV 文件。
    • 没问题,只需附加类似:... | Export-Csv C:\Toolbox\DataReport.csv -NoTypeInformation
    • 我也注意到了一种可能性。我会更新我的问题。
    【解决方案2】:

    我从未使用过 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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多