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

如何避免PowerShell中Import-Csv忽略空行?

问题:如何阻止PowerShell的Import-Csv忽略CSV文件中的空行?

背景

我有一个包含空行和单元格内换行的CSV文件,内容如下:

Richard Roe
Mary Major
"Alex Smith
Betty Brown
Chris Clark"

"Betty Brown
Donna Davis
Edward Evans"

Alex Smith

"Richard Roe
Mary Major"

我需要编写PowerShell脚本读取该CSV文件,并生成如下结果(在列表中插入对应部门名称):

"Legal
Richard Roe"
"Accounting
Mary Major"
"R&D
Alex Smith
Betty Brown
Design
Chris Clark"

"R&D
Betty Brown
Design
Donna Davis
Edward Evans"

"R&D
Alex Smith"

"Legal
Richard Roe
Accounting
Mary Major"

遇到的问题

使用Import-CSV读取该CSV文件时,会自动忽略空行,执行结果如下:

PS C:\tmp> Import-Csv -Header Names .\NamesList.csv

Names
-----
Richard Roe
Mary Major
Alex Smith...
Betty Brown...
Alex Smith
Richard Roe...


PS C:\tmp>

我期望的读取结果是保留原文件中的空行,如下所示:

Names
-----

Richard Roe
Mary Major
Alex Smith...

Betty Brown...

Alex Smith

Richard Roe...

虽然可以改用Get-Content读取文件,但处理单元格内的换行逻辑会变得非常复杂。

核心疑问

是否有办法阻止Import-Csv忽略CSV文件中的空行?

补充信息

另有一个存储部门-名称映射关系的CSV文件,内容如下:

Legal,Richard Roe
Accounting,Mary Major
R&D,Alex Smith
R&D,Betty Brown
Design,Chris Clark
Design,Donna Davis
Design,Edward Evans

解决方案

Import-Csv本身没有内置参数保留空行(因为CSV规范中空行通常被视为无效行),但可以通过以下两种方法实现需求:

方法1:预处理文件,标记空行后再导入

先读取文件内容,将空行替换为表示空单元格的"",导入后再还原为空行:

# 读取原始文件,将空行替换为""(空CSV单元格)
$processedContent = Get-Content .\NamesList.csv -Raw -Encoding UTF8 | 
    ForEach-Object { $_ -replace '^\s*$', '""' }

# 将处理后的内容转为CSV对象
$csvData = $processedContent | ConvertFrom-Csv -Header Names

# 遍历结果,把标记的空单元格还原为空行对应的空对象
$csvData | ForEach-Object {
    if ([string]::IsNullOrEmpty($_.Names)) {
        [PSCustomObject]@{ Names = $null }
    }
    else {
        $_
    }
}

方法2:使用.NET TextFieldParser解析(推荐)

借助.NET的TextFieldParser组件,它可以正确识别带换行的单元格,同时保留空行:

# 加载必要的程序集
Add-Type -AssemblyName Microsoft.VisualBasic

# 初始化解析器
$parser = New-Object Microsoft.VisualBasic.FileIO.TextFieldParser -ArgumentList ".\NamesList.csv"
$parser.SetDelimiters(',')
$parser.HasFieldsEnclosedInQuotes = $true # 启用引号包裹字段的解析

$parsedResults = @()
while (-not $parser.EndOfData) {
    try {
        $fields = $parser.ReadFields()
        if ($fields -eq $null) {
            # 处理空行,添加空对象
            $parsedResults += [PSCustomObject]@{ Names = $null }
        }
        else {
            # 读取正常行的内容
            $parsedResults += [PSCustomObject]@{ Names = $fields[0] }
        }
    }
    catch {
        # 处理异常行,这里同样视为空行
        $parsedResults += [PSCustomObject]@{ Names = $null }
    }
}
$parser.Close()

# 输出包含空行的结果
$parsedResults

后续:插入部门名称

得到保留空行的CSV数据后,结合部门映射文件完成部门插入逻辑:

# 导入部门映射表
$departmentMap = Import-Csv .\DeptMap.csv -Header Department, Name

# 处理每个条目生成目标格式
$parsedResults | ForEach-Object {
    if (-not [string]::IsNullOrEmpty($_.Names)) {
        $nameList = $_.Names -split "`n" | ForEach-Object { $_.Trim() }
        $outputLines = @()
        foreach ($name in $nameList) {
            $dept = $departmentMap | Where-Object { $_.Name -eq $name } | Select-Object -ExpandProperty Department
            $outputLines += "$dept`n$name"
        }
        # 用引号包裹结果
        '"' + ($outputLines -join "`n") + '"'
    }
    else {
        # 空行直接输出空行
        ""
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 14:52:36