1

У меня есть очень большой файл CSV (данные для всех поездок на такси в Нью-Йорке в марте). Вторая строка пуста, что раздражает импорт PostgreSQL. я могу бежать

(gc file.csv) | ? {$_.trim() -ne "" } | set-content file_trimmed.csv

чтобы избавиться от ошибочной строки, но, поскольку она проверяет каждую строку, требуется очень много времени для запуска (файл находится на внешнем диске, а мой компьютер - картофель).

В любом случае, чтобы сделать это быстрее?

1 ответ1

1

использование

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>

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .