Повысить производительность функции PowerShell, удаляя дубликаты из CSV - PullRequest
0 голосов
/ 27 июня 2019

У меня есть требование использовать PowerShell для решения проблемы, когда у меня большой набор данных, содержащийся в CSV. Мне нужно прочитать CSV в память и обработать удаление всех дубликатов из CSV.

Основная проблема, связанная с этим, за исключением использования PowerShell, запуска объектов в памяти и т. Д., Заключается в том, что мне приходится оценивать определенные столбцы, чтобы идентифицировать дубликаты, а не целые строки.

Кроме того, мне нужно сохранить самую старую копию записи, основанную на столбце, который содержит первую наблюдаемую дату.

Я пробовал несколько разных вещей, таких как объект сортировки с уникальным обозначением.

Набор данных в CSV обычно содержит 1-5 миллионов строк, а столбец выглядит следующим образом:

"LastObserved","FirstObserved","ComputerName","ComputerID","Virtual","ComputerSerialID"
function Request-Dedupe ($data) {
    try {
        Write-Log -Message "Cycling through data to remove duplicates"

        $dedupe_data = @()
        $i = 0
        $n = 0
        foreach ($obj in $data |Sort-Object -Property FirstObserved) {
            if ($obj.ComputerSerialID -notin $dedupe_data.ComputerSerialID -and $obj.ComputerID -notin $dedupe_data.ComputerID) {
                $dedupe_data += $obj
                if ($current_data.ComputerID -contains $obj.ComputerID) {
                   $dedupe_data[$n].LastObserved = $current_time
                }
                $n ++
            }
            Write-Progress -Activity "Cycling through data to remove duplicates and correlate first observed time" -Status "$i items processed" -PercentComplete ([Double]$i / $data.count*100)
            $i ++
        }

        Write-Log -Message "Dedupe Complete"
        return $dedupe_data
    } catch {
        Write-Log -Level Error "Unable to sort and dedupe data"
    }
}
$current_time = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss")
$current_data = Import-Csv .\UniqueSystems.csv
$test = Request-Dedupe $current_data

Моей целью было бы ускорить вышеизложенное, возможно, используя C #.

Ожидаемый вывод удалит все дубликаты из CSV с сохранением самой старой даты «FirstObserved» для каждого найденного дубликата.

1 Ответ

1 голос
/ 28 июня 2019

Для повышения производительности следует избегать добавления в массив, а также поиска в массивах.Оба являются медленными операциями.

Если я правильно понимаю ваш вопрос, вы хотите сохранить уникальные записи с теми же «ComputerID» и «ComputerSerialID» и самым старым значением «FirstObserved».Это может быть достигнуто с помощью такой хеш-таблицы:

$unique = @{}
Import-Csv .\UniqueSystems.csv | ForEach-Object {
    $key = '{0}/{1}' -f $_.ComputerID, $_.ComputerSerialID
    if (-not $unique.Contains($key) -or $unique[$key].FirstObserved -gt $_.FirstObserved) {
        $unique[$key] = $_
    }
}
$unique.Values
...