PowerShell中Get-Content存储行号原理及Import-CSV同类功能实现疑问
Get-Content行号存储的底层逻辑
Get-Content返回的每行内容本质不是普通字符串,而是被封装为PSString类型的PSObject对象,PowerShell默认给这类对象附加了6个固定顺序的隐藏NoteProperty属性存储文件元数据,顺序如下:
- PSPath:文件的完整绝对路径
- PSParentPath:文件所属父目录的完整路径
- PSChildName:文件名称
- PSDrive:文件所在的PS驱动器(比如C盘对应C:)
- PSProvider:对应的PowerShell提供程序标识
- ReadCount:读取行的行号,从1开始递增计数
$_.psobject.Properties.value[5]就是按索引取第6个属性的值,也就是行号。这种硬编码索引的写法兼容性和可读性都很差,你完全可以直接调用$_.ReadCount获取行号,效果完全一致。
为什么Import-CSV没有该特性
Import-CSV返回的是自定义结构的PSObject,每一个对象对应CSV的一行记录,PowerShell没有为这类对象默认附加文件读取相关的元数据属性,所以无法直接读取行号信息。
Import-CSV实现行号跟踪的方法
你可以在导入CSV的过程中手动给每一行附加行号属性,实现和Get-Content一致的行号调用体验,示例代码如下:
# 导入CSV并附加LineNumber行号属性 $csvContent = Import-Csv -Path "目标文件路径.csv" | ForEach-Object -Begin { $lineCount = 1 } -Process { # 给当前行附加行号属性并返回对象 $_ | Add-Member -MemberType NoteProperty -Name "LineNumber" -Value $lineCount -PassThru $lineCount++ } # 后续调用时直接访问LineNumber属性即可 foreach ($row in $csvContent) { Write-Host "当前处理行号:$($row.LineNumber),列1值:$($row.你的列名1)" }
示例代码优化
你提供的原示例代码可以替换为可读性更好的写法,避免硬编码属性索引:
Get-Content $colCnt | Where-Object { $_ } | Select-Object -Skip 1 | ForEach-Object { if ($_.Split("|").Count -ne 210) { "Process stopped at line number $($_.ReadCount), incorrect column count of: $($_.Split("|").Count)." break } }
内容的提问来源于stack exchange,提问作者immobile2
相关产品推荐
相关产品推荐

