You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell脚本拆分CSV时双引号转义异常求助

解决PowerShell拆分CSV时双引号转义异常问题

你的问题出在直接按物理行读取CSV文件——CSV规范中,字段内的双引号会用两个双引号转义(如"字段内容包含""双引号""),甚至允许字段内存在换行。原脚本的ReadLine()会把这类逻辑行拆成多个物理行,导致后续写入时重复输出、内容错乱。

改用Microsoft.VisualBasic.FileIO.TextFieldParser来解析CSV,它能正确识别CSV的逻辑行(包括带转义引号、字段内换行的情况),修改后的Split-File函数如下:

param([string]$in_file, [string]$out_folder, [int]$linesperFile = 100000, [string]$ext = 'csv', [string]$header='Y', [string]$compress='Y')

Function Split-File{
    Param(
        $in_file,
        $out_folder,
        $linesperFile,
        $ext,
        $header
    )
    # 加载TextFieldParser所需的程序集
    Add-Type -AssemblyName Microsoft.VisualBasic

    $filecount = 1
    $parser = $null
    $header_row = $null
    $writer = $null

    try{
        # 初始化CSV解析器,指定分隔符为逗号,双引号为引号字符
        $parser = New-Object Microsoft.VisualBasic.FileIO.TextFieldParser($in_file)
        $parser.TextFieldType = [Microsoft.VisualBasic.FileIO.FieldType]::Delimited
        $parser.SetDelimiters(',')
        $parser.HasFieldsEnclosedInQuotes = $true

        # 读取表头
        if ($header -ne 'N') {
            $header_row = $parser.ReadFields()
        }

        # 创建第一个输出文件
        $outputPath = Join-Path $out_folder "$($filecount.ToString("000")).$ext"
        $writer = [io.file]::CreateText($outputPath)
        $filecount++
        $linecount = 0

        # 写入表头(如果需要)
        if ($header -eq 'Y') {
            # 将表头数组转为CSV格式行(处理引号)
            $writer.WriteLine(($header_row | ForEach-Object { 
                if ($_ -match '["",\r\n]') { "`"$($_.Replace('"', '""'))`"" } else { $_ }
            }) -join ',')
        }

        # 逐逻辑行读取并写入
        while (!$parser.EndOfData) {
            try {
                $fields = $parser.ReadFields()
                # 将字段数组转为符合CSV规范的行
                $csvLine = ($fields | ForEach-Object { 
                    if ($_ -match '["",\r\n]') { "`"$($_.Replace('"', '""'))`"" } else { $_ }
                }) -join ','
                
                $writer.WriteLine($csvLine)
                $linecount++

                # 达到行数限制时切换文件
                if ($linecount -ge $linesperFile -and !$parser.EndOfData) {
                    $writer.Dispose()
                    $outputPath = Join-Path $out_folder "$($filecount.ToString("000")).$ext"
                    $writer = [io.file]::CreateText($outputPath)
                    $filecount++
                    $linecount = 0

                    # 新文件写入表头(如果需要)
                    if ($header -eq 'Y') {
                        $writer.WriteLine(($header_row | ForEach-Object { 
                            if ($_ -match '["",\r\n]') { "`"$($_.Replace('"', '""'))`"" } else { $_ }
                        }) -join ',')
                    }
                }
            } catch [Microsoft.VisualBasic.FileIO.MalformedLineException] {
                Write-Warning "跳过格式错误的行: $($_.Exception.Message)"
            }
        }
    } finally {
        # 清理资源
        if ($writer) { $writer.Dispose() }
        if ($parser) { $parser.Close() }
    }
    return $filecount - 1
}

修改说明

  1. 使用TextFieldParser:专门处理CSV格式,自动识别带引号的字段、字段内换行,避免物理行拆分错误。
  2. 正确生成CSV行:写入时对包含引号、逗号或换行的字段重新添加双引号,并转义内部的双引号(替换为两个双引号),符合CSV规范。
  3. 错误处理:跳过格式错误的行,避免脚本中断。

内容的提问来源于stack exchange,提问作者PracticingPython

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 13:50:25