-сплит функция не работает в большом файле Powershell - PullRequest
0 голосов
/ 28 февраля 2020

Я пытаюсь использовать Powershell для разбора CSV-файла, но функция split не работает. Я сравниваю вывод файла, используя разделенную и необработанную строку. Сплит работает только для первых нескольких строк. Я не знаю, что я что-то упустил. Вот мой код

$table = Get-Content .\random.csv -ReadCount 1000

$fname_mid = 'ps.mid'
$fname_mif = 'ps.mif'

New-Item -Path . -Name $fname_mid -ItemType 'file' -Force
New-Item -Path . -Name $fname_mif -ItemType 'file' -Force

ForEach($_ In $table) 
{
    $read_field = $_ -split ','
    $read_line = '----' + $read_field[0] + ',-' + $read_field[9] + '-'

    $read_line | Out-File -Encoding 'UTF8' -FilePath $fname_mid -Append
    $_ | Out-File -Encoding 'UTF8' -FilePath $fname_mif -Append
}

Файл для тестирования https://www.dropbox.com/s/99zgerh2akemgy3/random.csv?dl=0

1 Ответ

2 голосов
/ 28 февраля 2020

Принято вопросов по вашему вопросу (также перечисленных в комментариях) в аккаунте:

  • От @ Lee_Dailey :
    это >>> ForEach($_ In $table) <<< действительно не вызовет ошибку. переменная $ _ представляет собой текущий элемент конвейера <strong> ... и вы не используете конвейер. замените его на соответствующую переменную текущего элемента [возможно, $T_Item] и посмотрите, что произойдет.
  • From @ JosefZ :
    -ReadCount Указывает, сколько строк контента будет отправлено через трубопровод за один раз. Следовательно,
    $Table.Count => 40 и $Table[0].Gettype() => Object[] и
    ($Table[0] -split [System.Environment]::NewLine).Count => 1000 и
    ($Table[-1] -split [System.Environment]::NewLine).Count => 233
  • У вас есть 9 столбцы в предоставленном примере, что означает, что последний элемент -
    $read_field[8] (8 не 9 )
  • Это утверждение, $_ | Out-File -Encoding 'UTF8' -FilePath $fname_mif -Append мало что делает (если ваш источник не UTF8, но есть и другие способы сделать sh то же самое)
  • Как Вы хотите обработать кавычки во входном файле?

Вы получите что-то вроде:

$table = Get-Content .\random.csv

$fname_mid = 'ps.mid'
$fname_mif = 'ps.mif'

New-Item -Path . -Name $fname_mid -ItemType 'file' -Force
New-Item -Path . -Name $fname_mif -ItemType 'file' -Force

ForEach($Line In $table) 
{
    $read_field = $Line -split ','
    $read_line = '----' + $read_field[0] + ',-' + $read_field[8] + '-'

    $read_line | Out-File -Encoding 'UTF8' -FilePath $fname_mid -Append
    # $Line | Out-File -Encoding 'UTF8' -FilePath $fname_mif -Append
}

Но вы недооцениваете производительность (и простоту использования) Import-csv (как прокомментировано @ Уолтер Митти ) и сложный конвейер PowerShell, который поставляется с ним. Дело в том, что вы не можете просто основать свои измерения производительности на одной команде , если хотите сравнить ее с командлетами, созданными для потоковой передачи. В таком случае вам потребуется измерить полное решение .

Если ваш (исправленный) пример занимает более 7 минут ,
потоковая передача займет менее чем 3 секунд :

Import-Csv .\random.csv -Head (0..8) | 
ForEach-Object {"----$($_.0),-$($_.8)-"} | 
Set-Content .\fname_mid
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...