Настройка производительности Powershell для операции агрегирования файлов с большими разделителями

У меня есть файл с разделителями на 350 столбцов. Разделитель \034(Field separator). Мне нужно извлечь конкретное значение столбца и узнать количество каждого отдельного значения этого столбца в файле. Если количество различных значений больше или равно 2, мне нужно вывести его в файл. Размер исходного файла составляет 1 ГБ. Я написал следующую команду. Это очень медленно.

          Get-Content E:\Test\test.txt | Foreach {($_ -split '\034')[117]} | Group-Object -Property { $_ } | %{ if($_.Count -ge 2) { Select-Object -InputObject $_ -Property Name,Count} } | Export-csv -Path "E:\Test\test2.csv" -NoTypeInformation

Пожалуйста помоги!

1 ответ

Я предлагаю использовать switchоператор для быстрой обработки входного файла (по стандартам PowerShell):

      # Get an array of all the column values of interest.
$allColValues = switch -File E:\Test\test.txt {
  default {  # each input line
    # For better performance with *literal* separators, 
    # use the .Split() *method*.
    # Generally, however, use of the *regex*-based -split *operator* is preferable.
    $_.Split([char] 0x1c)[117] # hex 0x1c is octal 034
  }
}

# Group the column values, and only output those that occur at least 
# twice.
$allColValues | Group-Object -NoElement | Where-Object Count -ge 2 |
  Select-Object Name, Count | Export-Csv E:\Test\test2.csv -NoTypeInformation

Подсказка Mathias R. Jessen за то, что он предложил -NoElementкоммутатор, который оптимизирует вызов, сохраняя только абстрактную групповую информацию; то есть только критерии группировки (как отражено в .Name, а не отдельные объекты, составляющие группу (как обычно .Group) возвращаются через выходные объекты.


Что касается того, что вы пробовали :

  • с построчной потоковой передачей в конвейере происходит медленно , как обычно ( передача от объекта к объекту приводит к накладным расходам), так и, в частности , потому, что Get-Content украшает каждую выводимую строку метаданными ETS (Extended Type System).

    • В выпуске GitHub № 7537 предлагается добавить способ отказа от этого оформления.
    • За счет потребления памяти и потенциально дополнительной работы по разделению строк -Rawswitch считывает весь файл как одну многострочную строку, что намного быстрее.
  • Проходящий -Property { $_ } к Group-Objectне обязательно - просто пропустите. Без -Propertyаргумент, входные объекты группируются как единое целое .

  • Цепочка Where-Object а также - вместо фильтрации через if заявление в ForEach-Objectвызов в сочетании с несколькими Select-Object звонки - не только концептуально понятнее, но и работает лучше.


Другие вопросы по тегам