Транспонировать строку CSV в столбец на основе значения столбца - PullRequest
0 голосов
/ 13 мая 2018

Я пытаюсь преобразовать CSV-данные строки 80K с 30 столбцами в отсортированный и отфильтрованный CSV на основе определенных данных столбца из оригинального CSV.

Например, мои данные в следующем формате:

PatchName   MachineName IPAddress       DefaultIPGateway    Domain Name USERID          UNKNOWN NOTAPPLICABLE   INSTALLED   APPLICABLE  REBOOTREQUIRED  FAILED
KB456982    XXX1002     xx.yy.65.148    xx.yy.64.1          XYZ.NET     XYZ\ayzuser     YES     
KB589631    XXX1003     xx.yy.65.176    xx.yy.64.1          XYZ.NET     XYZ\cdfuser             YES
KB456982    ABC1004     xx.zz.83.56     xx.zz.83.1          XYZ.NET     XYZ\mnguser     YES
KB456982    8797XCV     xx.yy.143.187   xx.yy.143.184       XYZ.NET     WPX\abcuser                                                                     YES

Здесь MachineName будет отфильтровываться в Uniq, а PatchName будет транспонировать заголовки последних столбцов с удерживанием столбцов «UNKNOWN, NOAPPLICABLE, INSTALLED, FAILED, REBOOTREQUIRED». Значения, если произошло YES -

Ожидаемый результат:

MachineName IPAddress       DefaultIPGateway    Domain Name USERID          KB456982 KB589631 
XXX1002     xx.yy.65.148    xx.yy.64.1          XYZ.NET     XYZ\ayzuser     UNKNOWN  
XXX1003     xx.yy.65.176    xx.yy.64.1          XYZ.NET     XYZ\cdfuser              NOTAPPLICATBLE
ABC1004     xx.zz.83.56     xx.zz.83.1          XYZ.NET     XYZ\mnguser     UNKNOWN
8797XCV     xx.yy.143.187   xx.yy.143.184       XYZ.NET     WPX\abcuser     FAILED      

Требуется помощь для достижения этой цели, поэтому я могу транспонировать строки PathcName в столбцы, но не могу включить все столбцы вместе и применить условие. [Для обработки этого требуется 40 минут]

$b = @()
    foreach ($Property in $a.MachineName | Select -Unique) {
        $Props = [ordered]@{ MachineName = $Property }
        foreach ($Server in $a.PatchName | Select -Unique){ 
            $Value = ($a.where({ $_.PatchName -eq $Server -and $_.MachineName -eq $Property })).NOTAPPLICABALE
            $Props += @{ $Server = $Value }
        }
        $b += New-Object -TypeName PSObject -Property $Props
    }

1 Ответ

0 голосов
/ 14 мая 2018

Вот что я придумал:

$data = Import-Csv -LiteralPath 'C:\path\to\data.csv'

$lookup = @{}
$allPatches = $data.PatchName | Select-Object -Unique

# Make 1 lookup entry for each computer, to keep the username and IP and so on.
# Add the patch details from the current row (might add more than one patch per computer)
foreach ($row in $data)
{
    if (-not $lookup.ContainsKey($row.MachineName))
    {     
        $lookup[$row.MachineName] = ($row | Select-Object -Property MachineName, IPAddress, DefaultIPGateway, DomainName, UserID)
    }

    $patchStatus = $row.psobject.properties | 
            Where-Object {
                $_.name -in @('applicable', 'notapplicable', 'installed', 'rebootrequired', 'failed', 'unknown') -and 
                -not [string]::IsNullOrWhiteSpace($_.value)
            } | 
            Select-Object -ExpandProperty Name

    $lookup[$row.MachineName] | Add-Member -NotePropertyName $row.PatchName -NotePropertyValue $patchStatus

}

# Pull the computer details out of the lookup, and add all the remaining patches
# so they will convert to CSV properly, then export to CSV
$lookup.Values | ForEach-Object {
    $computer = $_
    foreach ($patch in $allPatches | where-object {$_ -notin $computer.psobject.properties.name})
    {
        $computer | Add-Member -NotePropertyName $patch -NotePropertyValue ''
    }
    $computer
} | Export-Csv -LiteralPath 'c:\path\to\output.csv' -NoTypeInformation
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...