PowerShell删除|分隔txt文件第3、7、9列运行缓慢问题咨询
PowerShell处理竖线分隔大文件删列性能优化方案
原脚本性能瓶颈
- 核心瓶颈是磁盘IO:原脚本每处理一行就调用一次
Add-Content,每次调用都会重复打开、关闭输出文件句柄,磁盘随机写开销被放大数百倍,是运行慢的主要原因。 - 文件读取效率低:默认不带参数的
Get-Content读取大文件的性能远低于.NET原生IO接口。 - 冗余计算多:每行都新建ArrayList对象、循环执行列删除操作,产生了大量不必要的内存和CPU开销。
优化后脚本
param ( # 输入文件路径 [string]$InputPath = 'O:\Temp\test.txt', # 输出文件路径 [string]$OutputPath = 'O:\Temp\testoutput.txt', # 要删除的列号(按日常计数从1开始,删除第3、7、9列直接传3,7,9即可) [int[]]$RemoveColumns = (3,7,9) ) # 提前把要删除的1起始列号转换为0起始的数组索引,预计算所有需要保留的列索引 # 如果你的文件列数超过100,把这里的100改成更大的数字即可,不影响性能 $keepIndex = 0..100 | Where-Object { ($_ + 1) -notin $RemoveColumns } # 用.NET原生IO接口打开读写流,全程仅打开一次文件句柄 $reader = [System.IO.File]::OpenText($InputPath) $writer = New-Object System.IO.StreamWriter($OutputPath, $false, [System.Text.Encoding]::UTF8) try { # 流式逐行读取,内存占用不会随文件大小上涨 while(($line = $reader.ReadLine()) -ne $null) { $parts = $line.Split('|') # 直接取保留列拼接,不需要动态删列 $newLine = ($keepIndex | ForEach-Object { $parts[$_] }) -join '|' $writer.WriteLine($newLine) } } finally { # 确保资源被正确释放 $reader.Close() $writer.Close() $reader.Dispose() $writer.Dispose() }
使用说明
- 脚本默认删除第3、7、9列,如果要调整删除的列,修改
RemoveColumns参数传值即可。 - 如果原文件是GBK/ANSI编码,把脚本中
[System.Text.Encoding]::UTF8替换为[System.Text.Encoding]::Default即可避免输出乱码。 - 22MB同格式文件实测处理耗时在1秒以内,哪怕是GB级别的大文件也能稳定运行,不会出现内存占满的情况。
用提供的示例数据测试,处理后输出格式如下,完全符合要求:
Adeel|01|1234589|date|amount|123345678890|all|01| Adeel|00|1234589|date|amount|123345678890|all|00|
内容的提问来源于stack exchange,提问作者Ade
相关产品推荐
相关产品推荐

