我有大量的CSV文件,我试图用Powershell导入0.5-2gb +文件。
数据如下:
姓名,日期,价值
"乔,约翰",2016-08-01,"价值"
"史密斯,简",2016-08-01,"价值" ...
我有这个功能
$elapsed = [System.Diagnostics.Stopwatch]::StartNew()
$reader = new-object System.IO.StreamReader($csv)
while (($line = $reader.ReadLine()) -ne $null) {
# Use RegEx to only split on (,) outside quotes and remove quoted strings
$row = ($line -split ',(?=(?:[^"]|"[^"]*")*$)').Replace("`"","")
# Row Indicator
$i++;
if (($i % 50000) -eq 0) {
Write-Host "$i rows have been processed in $($elapsed.Elapsed.ToString())."
}
}
用逗号分隔该行","因为我得到〜16K一秒,但是我只需要在任何引号之外拆分,所以我实现了正则表达式,但是性能可以达到每秒900行。
我正在寻找一种更有效的循环CSV文件的方法,该文件以逗号分隔,但在引号中包含需要排除的逗号。
答案 0 :(得分:3)
如上面的评论中所述,Import-Csv不会将所有内容加载到内存中,除非您要求它。与问题中的示例一样,它实现了一个流阅读器,并将其读取的内容推送到输出管道。
如果您执行以下操作,您将看到大量内存使用情况:
$var = Import-Csv thefile.csv
毕竟,CSV的内容必须在某处。
然而,如果您对输出管道执行某些操作,则影响较小。 e.g。
Import-Csv thefile.csv | ForEach-Object {
Do-Something
}
最后,Import-Csv真的不适合你我有一个CSV阅读器类以及github上名为Indented.Text.Csv的Import-Csv的并行实现。此实现为公共类提供了我需要的许多功能,因此我可以非常快速地处理CSV文件。