比较CSV中的2列,如果匹配则创建一个新列

时间:2020-07-01 16:06:01

标签: powershell

我有一个Powershell脚本,正在对几个数据库进行SQL查询。 它将结果吐出到我的桌面上的CSV文件中。 我希望Powershell脚本比较两个列,如果它们匹配则创建一个新列。

这只是节省了我每次在excel中进行比较的时间。

我只是对powershell不够了解。

CSV中的当前结果是这样的。

    Name      PhoneNumber       PhoneNumberInDB2    
   Person 1    1112223333          1112223333
   Person 2    4445556666          7778889999

我希望脚本修改csv来做到这一点。

    Name      PhoneNumber       PhoneNumberInDB2    Match?
   Person 1    1112223333          1112223333         Y
   Person 2    4445556666          7778889999         N

我已经看过几个脚本,如何比较多个csv并创建一个新的csv ...,但我宁愿只是修改从SQL查询创建的csv。

如果有帮助...这是实际CSV文件的复制和粘贴,我编辑了电话号码以保护客户...我正在查看exel中的csv。

    ID  Phone   DB2Phone
5521350 1112223333  1112223333

在记事本中:

"ID","Phone","PhoneID"
"5521350","1112223333","1112223333"

3 个答案:

答案 0 :(得分:1)

$Data = Import-Csv "file.csv"
ForEach ($obj in $Data) {
$hashtable = [ordered]@{}
ForEach ($property in $obj.PSObject.properties.name) { $hashtable[$property] = $obj.$property }
$hashtable["match?"] = If ($obj.'PhoneNumber' -eq $obj.'PhoneNumberInDB2') {"Y"} Else {"N"}
$Data = $Data -ne $obj
$Data += New-Object -TypeName PSObject -Property $Hashtable
}

答案 1 :(得分:1)

如果我没看错,也许您可​​以使用Select-Object将该属性添加到传入的对象中。听起来您要比较的2个属性在任何给定时间都在同一对象内。因此,您应该可以将其简化为单个管道...

类似的东西:

$Data = Import-Csv "file.csv" |
Select-Object *,
    @{Name = 'Match'; Expression = { If( $_.PhoneNumber -eq $_.PhoneNumberInDB2 ){ 'Y' } Else { 'N' } } }

注意:我删除了“?”在新的属性(列)名称上。

如果您需要重新导出以重新导出到相同的Csv文件,只需将$Data传送到Export-Csv即可:

$Data = Import-Csv "file.csv" |
Select-Object *,
    @{Name = 'Match?'; Expression = { If( $_.PhoneNumber -eq $_.PhoneNumberInDB2 ){ 'Y' } Else { 'N' } } }

$Data | Export-Csv "file.csv" -NoTypeInformation

以上假设如果您想更改文件名,可以将其放在单个管道中,例如:

Import-Csv "file.csv" |
Select-Object *,
    @{Name = 'Match?'; Expression = { If( $_.PhoneNumber -eq $_.PhoneNumberInDB2 ){ 'Y' } Else { 'N' } } } | 
Export-Csv "file_new.csv" -NoTypeInformation

注意:此修订不需要$Data。由于所有内容都在管道中,因此可以提高内存效率。除非文件很大,但这通常不是问题。

答案 2 :(得分:1)

这是完成这项工作的另一种方式... [咧嘴]它的作用...

  • 无法读取CSV文件
    当您准备好进行此操作时,只需将整个#region/#endregion块替换为Import-CSV调用即可。
  • 遍历整个收藏集
  • 创建具有所需属性的新对象
  • 比较两个电话号码,并将其保存到SamePhoneNumber属性中
    您可以根据需要将这些False/True项替换为N/Y。只需在第19和20行上交换注释标记即可。如果您要进行更多处理,False/True的效果比单纯的字母还要好,因为它会在PoSh中自动转换为布尔值。
  • 将新对象发送到OutStuff集合
  • 在屏幕上显示

代码...

#region >>> fake reading in a CSV file
#    in real life, use Import-CSV
$InStuff = @'
"ID","Phone","PhoneID"
"5521350","1112223333","1112223333"
"2020202","2020202020","2000000002"
"3030303","3030303030","3030303030"
"4040404","4040404040","4000000004"
'@ | ConvertFrom-Csv
#endregion >>> fake reading in a CSV file

$OutStuff = foreach ($IS_Item in $InStuff)
    {
    [PSCustomObject]@{
        ID = $IS_Item.Id
        Phone = $IS_Item.Phone
        PhoneId = $IS_Item.PhoneId
        # if you want `N/Y` instead of `False/True`, swap the comment markers for lines 19 & 20
        SamePhoneNumber = $IS_Item.Phone -eq $IS_Item.PhoneId
        #SamePhoneNumber = @('N', 'Y')[$IS_Item.Phone -eq $IS_Item.PhoneId]
        }
    }

$OutStuff

带有布尔值的输出...

ID      Phone      PhoneId    SamePhoneNumber
--      -----      -------    ---------------
5521350 1112223333 1112223333            True
2020202 2020202020 2000000002           False
3030303 3030303030 3030303030            True
4040404 4040404040 4000000004           False

输出为N/Y ...

ID      Phone      PhoneId    SamePhoneNumber
--      -----      -------    ---------------
5521350 1112223333 1112223333 Y              
2020202 2020202020 2000000002 N              
3030303 3030303030 3030303030 Y              
4040404 4040404040 4000000004 N