如何用PowerShell仅覆盖CSV指定列新数据且保留原有数据?
CSV指定列数据覆盖实现方案
初始CSV数据
Underlying,AllBlue,AllRed AUD,1/5/2024, BRR,, GBP, 3/10/2024, CAD,,
2024/04/29生成的新CSV数据
Underlying,AllBlue,AllRed AUD,, BRR,4/29/2024, GBP,4/29/2024, CAD,,4/29/2024
需求
仅将新CSV中AllBlue和AllRed列的非空数据,覆盖到原CSV对应Underlying行的同列,保留原CSV已有非空数据,最终得到:
Underlying,AllBlue,AllRed AUD,1/5/2024, BRR ,4/29/2024, GBP,4/29/2024, CAD,,4/29/2024
当前脚本问题
原脚本只是将两个CSV的所有行追加合并,没有根据Underlying匹配行并覆盖指定列,导致输出出现重复行,不符合需求。
正确实现脚本
# 定义文件路径 $originalCsvPath = "C:\Sandbox\test\original.csv" $newCsvPath = "C:\Sandbox\test\new.csv" $outputCsvPath = "C:\Sandbox\testoutput\colors.csv" # 导入原CSV和新CSV数据 $originalData = Import-Csv -Path $originalCsvPath $newData = Import-Csv -Path $newCsvPath # 将新数据转为哈希表,以Underlying(去除首尾空格)为键,快速匹配行 $newDataLookup = @{} foreach ($item in $newData) { $newDataLookup[$item.Underlying.Trim()] = $item } # 遍历原数据,更新指定列 foreach ($originalItem in $originalData) { $underlyingKey = $originalItem.Underlying.Trim() if ($newDataLookup.ContainsKey($underlyingKey)) { $newItem = $newDataLookup[$underlyingKey] # 仅当新数据AllBlue非空时覆盖原数据 if (-not [string]::IsNullOrEmpty($newItem.AllBlue)) { $originalItem.AllBlue = $newItem.AllBlue } # 仅当新数据AllRed非空时覆盖原数据 if (-not [string]::IsNullOrEmpty($newItem.AllRed)) { $originalItem.AllRed = $newItem.AllRed } } } # 导出最终结果 $originalData | Export-Csv -Path $outputCsvPath -NoTypeInformation
关键说明
- 使用哈希表存储新数据,通过
Underlying键快速定位对应行,避免循环嵌套提升效率 - 对
Underlying值做去除首尾空格处理,解决原CSV中BRR带空格、新CSV不带空格的匹配问题 - 仅在新数据对应列非空时才覆盖原数据,确保原CSV已有非空数据被保留
- 直接修改原数据数组后导出,不会产生追加行的问题
内容的提问来源于stack exchange,提问作者iceman
相关产品推荐
相关产品推荐

