PowerShell筛选CSV中Scenario列为And的行导出结果不符合预期
问题说明
现有sample.csv文件,原始内容如下:
#Period,Account,Entity,Year,Version,Currency,HSP_Rates,Scenario,Data Apr,1,9,FY22,F,L,H,And,2 Apr,1,9,FY22,F,L,H,And,2 Apr,1,9,FY22,F,L,H,OR,2
需求为过滤Scenario字段值仅等于And的记录,导出为新CSV文件,预期输出内容如下:
#Period,Account,Entity,Year,Version,Currency,HSP_Rates,Scenario,Data Apr,1,9,FY22,F,L,H,And,2 Apr,1,9,FY22,F,L,H,And,2
原有自行编写的PowerShell脚本运行后无法得到符合要求的输出,脚本内容如下:
$csvRaw = Get-Content -Path 'D:\sample.csv' -Raw $Csv = $CsvRaw.TrimStart('#') | ConvertFrom-Csv $NewCsv = $csv | ForEach-Object { [PsCustomObject]@{ Period = $_.Period Account = $_.Account Entity = $_.Entity Year = $_.Year Version = $_.Version Currency = $_.Currency HSP_Rates = $_.HSP_Rates Scenario = $_.Scenario | where {$_.Scenario -match "And" } Data = $_.Data } } $OutCsv = ($NewCsv | ConvertTo-Csv -NoTypeInformation).TrimStart('"#') # Converting back to CSV surround everything with double quotes. # We need to insert back the hash sign for the #period header$OutCsv[0] = """#" + $OutCsv[0] $OutCsv | Out-File 'D:\sample_1.csv'
脚本错误点排查
原有脚本共有4个核心问题:
- 行过滤逻辑位置完全错误:过滤整行的
Where-Object写在了构造自定义对象的Scenario属性赋值语句里,既没有筛掉Scenario=OR的行,还会因为当前管道元素是字符串(Scenario的字段值)、不存在.Scenario属性,导致Scenario列输出异常。 - 匹配规则不符合需求:用
-match做模糊匹配,若存在Scenario字段值包含And但不等于And的记录会被误保留,需求是精确匹配字段值,应该用-eq做相等判断。 - 多余的对象重建逻辑:CSV通过
ConvertFrom-Csv转成对象后,不需要逐字段手动重新赋值生成新对象,直接过滤原对象即可,手动赋值容易出现字段遗漏、拼写错误。 - 表头#号处理逻辑混乱:用
TrimStart('"#')全局处理所有输出行容易误删正常内容,字符串拼接加#号的转义写法容易导致表头引号错乱、格式错误。
修正后可直接运行的脚本
# 读取原始文件,移除表头开头的#后转成CSV对象 $csvRaw = Get-Content -Path 'D:\sample.csv' -Raw $csvData = $csvRaw.TrimStart('#') | ConvertFrom-Csv # 过滤行:仅保留Scenario字段严格等于And的记录 $filteredData = $csvData | Where-Object { $_.Scenario -eq 'And' } # 转CSV格式,单独修正表头加回#号 $outputContent = $filteredData | ConvertTo-Csv -NoTypeInformation $outputContent[0] = $outputContent[0] -replace '^"Period', '"#Period' # 导出文件,指定UTF8编码避免乱码 $outputContent | Out-File 'D:\sample_1.csv' -Encoding utf8
内容的提问来源于stack exchange,提问作者Intern99
相关产品推荐
相关产品推荐

