PowerShell合并CSV文件时如何正确提取指定列并追加文件名
PowerShell 合并CSV仅保留指定列的实现方案
问题背景
当前使用PowerShell递归遍历目录,跳过顶层指定目录后读取近1天生成的CSV文件,原有逻辑是在每行末尾追加对应文件名后合并为单个文件。现有CSV固定包含ID、First Name、Last Name、Phone、Address5列,列名默认带双引号包裹,需求调整为合并时仅保留ID和Last Name列,外加追加的文件名列。
原有实现代码如下:
$mergedData= Get-ChildItem $path -Exclude yesterday,"OHCC Extract",output | Get-ChildItem -recurse -Filter *csv | Where-Object { $_.CreationTime -gt (Get-Date).AddDays(-1) } | % { $file = $_.Name $fn = $_.FullName ## capture the header line $FirstLine = Get-Content $fn -TotalCount 1 ## add the column header for filename $header = $FirstLine + ",Filename" ## get the contents of the files without the first line Get-Content $fn | SELECT -Skip 1 | %{ "$_,$file" } }
尝试的三种错误写法及现象:
- 写法1:
Get-Content $fn | SELECT -Skip 1 -Property ID | %{ "$_,$file" },结果出现@{ID=}格式异常内容 - 写法2:
Get-Content $fn | SELECT -Skip 1 | %{ $_.ID },返回空值 - 写法3:
Import-Csv -Path $fn -Delimiter ',' | SELECT ID,结果出现@{ID=73aec2fe-6cb3-492e-a157-25e355ed9691}格式异常内容
运行环境为Windows 10 自带PowerShell 5.1.19041.1682。
错误原因说明
- 前两种写法的核心问题:
Get-Content读取文件返回的是逐行纯字符串,不是结构化的CSV对象,本身不存在ID、Last Name这类属性,直接取属性会返回空;强行用Select-Object指定属性会生成空属性的自定义对象,对象转字符串时默认输出@{属性名=值}格式。 - 第三种写法的核心问题:
Import-Csv确实能把CSV解析为结构化对象,但直接把对象拼到字符串里输出时,PowerShell默认的对象转字符串逻辑就是输出@{属性名=值}格式,没有转换成符合CSV规范的逗号分隔文本。
正确实现代码
推荐使用PowerShell原生CSV cmdlet实现,自动处理双引号包裹、字段内含逗号等边界情况,不需要手动拼接字符串:
# 替换为你的CSV文件根目录实际路径 $path = "C:\your\csv\directory" Get-ChildItem $path -Exclude yesterday,"OHCC Extract",output | Get-ChildItem -Recurse -Filter *csv | Where-Object { $_.CreationTime -gt (Get-Date).AddDays(-1) } | ForEach-Object { $currentFile = $_ # 导入当前CSV,自动解析双引号包裹的列和字段,仅保留需要的列,追加Filename字段 Import-Csv -Path $currentFile.FullName -Delimiter ',' | Select-Object ID, 'Last Name', @{Name='Filename'; Expression={$currentFile.Name}} } | Export-Csv -Path (Join-Path $path "merged_result.csv") -NoTypeInformation -Encoding UTF8
代码说明
Import-Csv会自动识别CSV规范下的双引号字段包裹符,导入后列名会自动去掉外层双引号,直接用ID、Last Name即可访问对应列。- 计算属性
@{Name='Filename'; Expression={$currentFile.Name}}用于给每一行数据追加当前文件名,不需要手动逐行拼接。 - 最后通过
Export-Csv统一导出,自动生成一次标准表头,所有数据行自动转换为符合CSV规范的格式:-NoTypeInformation参数用于去掉PowerShell默认导出时开头的类型注释行-Encoding UTF8参数指定编码,避免中文等非ASCII字符乱码
内容的提问来源于stack exchange,提问作者GoGoPuffs
相关产品推荐
相关产品推荐

