快速拆分逗号分隔的CSV行,并在Powerhell中使用Strings周围的引号

时间:2016-08-19 18:26:55

标签: csv powershell

我有大量的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文件的方法,该文件以逗号分隔,但在引号中包含需要排除的逗号。

1 个答案:

答案 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文件。