使用PowerShell实现CSV文件结构化转换的技术问询
当然可以用PowerShell实现这两个需求!我会分两部分给你详细拆解代码和逻辑,你可以根据实际文件的细节调整参数:
需求1:合并Source-File-1与Source-File-2的内容
思路分析
观察两个文件的结构,Source-File-2的每行第11列(也就是VALUE10后面的数字列)是10、22、33这类标识值,和Source-File-1的第11列完全对应。我们的核心操作就是根据这个标识值匹配两行,把Source-File-1对应行的后续列内容追加到Source-File-2的行尾。
实现代码
# 读取Source-File-1,用临时列名避免无列名导致的解析错误(这里假设最多50列,可按需调整) $source1 = Import-Csv -Path "Source-File-1.csv" -Delimiter ';' -Header (1..50 | ForEach-Object { "Col$_" }) # 读取Source-File-2,同样指定临时列名 $source2 = Import-Csv -Path "Source-File-2.csv" -Delimiter ';' -Header (1..27 | ForEach-Object { "Col$_" }) # 逐行匹配并合并内容 $mergedResult = foreach ($row2 in $source2) { # 找到Source-File-1中第11列与当前行匹配的记录 $matchingRow1 = $source1 | Where-Object { $_.Col11 -eq $row2.Col11 } if ($matchingRow1) { # 提取Source-File-1中第12列到末尾的所有内容,用分号拼接 $appendContent = $matchingRow1.PSObject.Properties | Where-Object { $_.Name -match '^Col(1[2-9]|[2-5][0-9])$' } | ForEach-Object { $_.Value } $appendString = $appendContent -join ';' # 拼接Source-File-2的原内容与追加内容 $originalContent = $row2.PSObject.Properties | ForEach-Object { $_.Value } $originalString = $originalContent -join ';' "$originalString;$appendString" } else { # 若未找到匹配行,保留原行内容 $row2.PSObject.Properties | ForEach-Object { $_.Value } -join ';' } } # 将结果写入目标文件 $mergedResult | Out-File -Path "Merged-Output.csv" -Encoding UTF8
关键说明
- 用
-Header指定临时列名:因为你的CSV没有明确的列标题,PowerShell默认会把第一行当列名,所以我们手动指定Col1到ColN避免解析混乱。 - 匹配逻辑:通过
Col11(第11列)精准匹配两行,确保追加的内容对应正确。 - 编码设置:
-Encoding UTF8避免中文或特殊字符乱码,若你的文件是其他编码,可改成Default或UTF8BOM。
需求2:根据第26列值拆分生成多行并追加列内容
思路分析
核心逻辑是根据第26列的值分支处理:
- 当值为5时:把指定列的每个值拆分成单独行
- 当值为10时:生成10行对应内容
- 无论哪种情况,都要把第17列及之后的内容追加到每行末尾
实现代码
# 读取目标CSV,指定临时列名(假设最多50列,可按需调整) $targetCsv = Import-Csv -Path "Your-Third-Csv.csv" -Delimiter ';' -Header (1..50 | ForEach-Object { "Col$_" }) # 逐行处理生成输出内容 $outputRows = foreach ($row in $targetCsv) { $col26Value = $row.Col26 # 提取第17列到末尾的内容,用分号拼接成追加字符串 $appendContent = $row.PSObject.Properties | Where-Object { $_.Name -match '^Col(1[7-9]|[2-5][0-9])$' } | ForEach-Object { $_.Value } $appendString = $appendContent -join ';' if ($col26Value -eq '5') { # 这里假设需要拆分的是第11到15列(Col11-Col15),请根据实际需求修改列范围 $splitColumns = $row.PSObject.Properties | Where-Object { $_.Name -match '^Col(1[1-5])$' } | ForEach-Object { $_.Value } foreach ($val in $splitColumns) { # 拼接前10列 + 当前拆分值 + 追加内容 $prefixContent = $row.PSObject.Properties | Where-Object { $_.Name -match '^Col(1[0]|[1-9])$' } | ForEach-Object { $_.Value } $prefixString = $prefixContent -join ';' "$prefixString;$val;$appendString" } } elseif ($col26Value -eq '10') { # 生成10行,这里假设第11列填1到10,可根据需求修改此行的内容 for ($i=1; $i -le 10; $i++) { $prefixContent = $row.PSObject.Properties | Where-Object { $_.Name -match '^Col(1[0]|[1-9])$' } | ForEach-Object { $_.Value } $prefixString = $prefixContent -join ';' "$prefixString;$i;$appendString" } } else { # 其他值的情况,默认保留原行内容,可根据需求自定义处理 $row.PSObject.Properties | ForEach-Object { $_.Value } -join ';' } } # 将结果写入输出文件 $outputRows | Out-File -Path "Split-Output.csv" -Encoding UTF8
关键说明
- 拆分列的调整:代码中默认拆分第11-15列,如果你需要拆分其他列,修改
Where-Object { $_.Name -match '^Col(1[1-5])$' }中的正则表达式即可(比如改成Col(1[6-8])就是拆分16-18列)。 - 10行内容的自定义:如果生成10行时需要填充的不是1-10,而是其他值,直接修改
for循环里的$i部分即可。 - 异常处理:代码中对非5、10的情况保留原行,你可以根据需求添加其他分支逻辑。
内容的提问来源于stack exchange,提问作者batchprog2020
相关产品推荐
相关产品推荐

