использование
gc file.csv | ? {$_.trim() -ne "" } | set-content file_trimmed.csv
Что не так в исходной команде (перефразировано Удалите все пустые строки из текстового файла с помощью PowerShell в блоге Тима Кервика о PowerShell):
Скобки вокруг оператора Get-Content
заставляют его завершить загрузку всего содержимого в объект перед отправкой его по конвейеру. (Если мы пишем в файл, отличный от того, из которого мы читали, мы могли бы ускорить выполнение команды, исключив скобки, что позволило бы нам читать из одного и записывать в другой одновременно.)
Тестовый скрипт 1264263.ps1
измеряет простое чтение большого файла и исключает запись в выходной файл:
param (
[Parameter()][string]$file = 'green_tripdata_2014-03.csv'
)
Push-Location 'D:\test'
#$file = 'green_tripdata_2014-03.csv'
"$file`: {0:N3} KiB" -f $((Get-Item $file).Length /1024 )
' GC $file :' + ' {0:N7} sec' -f (Measure-Command {
$y = Get-Content $file
}).TotalSeconds
Start-Sleep -Seconds 1
' GC $file | ? {$_.trim()} :' + ' {0:N7} sec' -f (Measure-Command {
$y = (Get-Content $file |
Where-Object {$_.trim()}) #| Set-Content "$file2"
}).TotalSeconds
Start-Sleep -Seconds 1
' GC $file | ? {$_.trim() -ne ""} :' + ' {0:N7} sec' -f (Measure-Command {
$y = (Get-Content $file |
Where-Object {$_.trim() -ne "" }) #| Set-Content "$file2"
}).TotalSeconds
Start-Sleep -Seconds 1
'(GC $file) | ? {$_.trim() -ne ""} :' + ' {0:N7} sec' -f (Measure-Command {
$y = (Get-Content $file) |
Where-Object {$_.trim() -ne ""} #| Set-Content "$file2"
}).TotalSeconds
Pop-Location
Вывод показывает, что улучшенная команда (вариант № 3) может работать примерно в 10 раз быстрее, чем оригинальная (случай № 4):
PS D:\PShell> D:\PShell\SU\1264263.ps1
green_tripdata_2014-03.csv: 197,355.560 KiB
GC $file : 27.4584778 sec
GC $file | ? {$_.trim()} : 59.2003851 sec
GC $file | ? {$_.trim() -ne ""} : 61.0429012 sec
(GC $file) | ? {$_.trim() -ne ""} : 615.8580773 sec
PS D:\PShell>