Powershell 基于列值将CSV行转换为列
我正在尝试将一个包含30列的80K行数据csv转换为基于原始csv中特定列数据的排序和过滤csv 例如,我的数据采用以下格式:Powershell 基于列值将CSV行转换为列,powershell,Powershell,我正在尝试将一个包含30列的80K行数据csv转换为基于原始csv中特定列数据的排序和过滤csv 例如,我的数据采用以下格式: PatchName MachineName IPAddress DefaultIPGateway Domain Name USERID UNKNOWN NOTAPPLICABLE INSTALLED APPLICABLE REBOOTREQUIRED FAILED KB456982 XXX1002 xx.
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将转置到最后一列标题,如果出现“是”,则保留“未知、不适用、已安装、失败、重新启动需要的列”值-
预期结果:
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
}
这就是我想到的:
$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
请注意,流的第一个对象上应存在所有属性,否则下一个cmdlet将无法获取(或显示)这些属性。请参阅:非常感谢您的响应,我对最近的评论表示歉意-下面是我收到的错误-
Add Member:无法添加名为“KB4057117”的成员“因为具有该名称的成员已存在。若仍要覆盖该成员,请将Force参数添加到命令中。在第22行字符:33+…hineName]|添加成员-NotePropertyName$row.PatchName-NoteProperty+CategoryInfo:InvalidOperation:(@{MachineName=A..U KB4057117=}:PSObject)[添加成员],InvalidOperationException+FullyQualifiedErrorId:MemberAlreadyExists,Microsoft.PowerShell.Commands.AddMemberCommand
我刚刚抑制了错误-ErrorAction SilentlyContinue
-它正在按预期生成数据,现在我将在180万行上运行此命令:)