首页 > 解决方案 > 使用powershell根据键更新csv的多列

问题描述

我有一个 powershell 脚本,它从 API 下载数据并将其导出到 .csv 文件。我希望能够定期运行它,只下载自上次 API 调用以来发生的变化并更新现有的 .csv 文件。

例如:

InitialData.csv
FormID,FormType,LastEditor,Status
F440,Permits,Bill,Opened
F443,Inspeciton,John,Opened
F446,Permits,Clare,Opened

Update.csv
FormID,FormType,LastEditor,Status
F440,Permits,Bill,Closed
F446,Permits,John,Opened
F449,Permits,Bill,Opened

Output.csv
FormID,FormType,LastEditor,Status
F440,Permits,Bill,Closed
F443,Inspeciton,John,Opened
F446,Permits,John,Opened
F449,Permits,Bill,Opened

如您所见,已编辑 2 条记录,并在更新过程中添加了 1 条记录。

如果我使用数据库服务器,我确信这会更容易,但我的选择仅限于使用 powershell 和 .csv 文件。

标签: powershellcsv

解决方案


发布的解决方案的问题是它没有考虑现有FormID值的其他列的更改。当有重复值时,您可以使用Group-Object来选择更新的内容。FormID

$initial = Import-Csv InitialData.csv
$update = Import-Csv Update.csv
$initial+$update | Group-Object FormID |
    Foreach-Object {
        $_.Group[-1]
    } | Export-Csv Output.csv -NoTypeInformation

解释:

Group-Object根据提供的属性名称 ( FormID) 对对象进行分组。每个具有匹配属性值的对象都被分组为一个GroupInfo对象。当将这些组通过管道传输到 时Foreach-Object$_.Group是一个包含这些对象的集合。$_.Group[0]将是第一个检查的包含匹配项的对象。$_.Group[1]将是包含匹配项的第二个对象。顺序由管道输入的对象的顺序决定Group-Object。PowerShell 的一个巧妙技巧是索引[-1],它始终是集合中的最后一个对象。因此,如果一个分组只产生一个[0]值或同时产生一个值[0]和一个[1]值,我们总是想要最后一个对象[-1],因为我们检查$updateafter $initial


推荐阅读