Process large CSV file from Powershell
Lucrul cu fisiere mari de tip CSV in Powershell s-a dovedit a fi un cosmar de multe ori. In special datorita faptului ca folosind Import-CSV aducem tot fisierul in memorie. Si daca avem de lucru cu fisiere de cativa GB atunci putem sa crash-uim foarte usor sistemul de pe care lucram.
Cautand o varianta pe internet sa citesc fisierul linie cu linie am gasit varianta sa folosesc [System.IO.File]::ReadLines descrisa pe aici.
foreach ($line in [System.IO.File]::ReadLines($filename)) { # do something with $line }
Dar nu am mai ajuns pana acolo pentru ca am descoperit ca si folosind Get-Content pot sa citesc fisierul linie cu linie. Exista si parametrul –ReadCount dar nu este nevoie de el, pentru ca by default Get-Content trimite prin pipeline linie cu linie. Toata chestia e sa nu ai dupa pipeline ceva ce stocheaza tot ce vine prin pipeline in memorie din nou.
Insa nu este tot. Nu poti trimite output-ul catre Import-CSV pentru ca acesta nu accepta decat path catre un fisier. Asa ca a fost nevoie sa folosesc ConvertFrom-Csv.
Get-Content .\mytestfile.csv | ConvertFrom-Csv
Iar output-ul dat mai departe de aceasta comanda poate fi prelucrat foarte usor cu Where-Object aka ?
Get-Content .\mytestfile.csv | ConvertFrom-Csv | ? {$_.Name –like ‘something*’}
Iar de aici putem insirui si alte conditii cu Where-Object sau sa folosim Select-Object pentru a selecta doar campurile dorite iar la final sa trimitem totul catre Export-Csv:
Get-Content .\mytestfile.csv | ConvertFrom-Csv | ? {$_.Name –like ‘something*’} |Export-Csv .\final.csv