0

I'm looking for some powershell to convert Listed properties into a CSV or Table, not all records in the list have the same Properties but the "Index" property signifies a new record.

INPUT

Index:1  
FirstName:Bob  
LastName:Smith  
DOB:1/1/1970  
Index:2  
FirstName:John  
DOB:1/1/1971  
Index:3  
LastName:Jones  
DOB:1/1/1972

OUTPUT

FirstName,LastName,DOB  
Bob,Smith,1/1/1970  
John,,1/1/1971  
,Jones,1/1/1972  

Any help is greatly appreciated. Thanks

4

2 回答 2

1

另一个例子。

$arrInputFile = Get-Content -Path "C:\temp\input.txt"
$strCSVExportPath = "C:\temp\Export.csv"

$arrCSVHeader = @()
Foreach ($strLine in $arrInputFile) {
    If ($arrCSVHeader -notcontains $strLine.Split(":")[0]) {
        $arrCSVHeader += $strLine.Split(":")[0]
    }        
}

$arrCSVOutput = @()
$objCurrentIndexBlock = $null
Foreach ($strLine in $arrInputFile) {    
    If ($strLine.Split(":")[0] -eq "Index") {
        If ($objCurrentIndexBlock -ne $null) {
            $arrCSVOutput += $objCurrentIndexBlock
        }

        $objCurrentIndexBlock = "" | Select-Object -Property $arrCSVHeader
    }

    $objCurrentIndexBlock.$($strLine.Split(":")[0]) = $strLine.Split(":")[1].Replace(" ",$null)

}
$arrCSVOutput += $objCurrentIndexBlock

$arrCSVOutput | Export-Csv -Path $strCSVExportPath -NoClobber -NoTypeInformation -Force
于 2014-08-23T11:01:09.197 回答
0

您可以通过 ForEach 运行它并查找 Index 以创建一个对象,然后向其添加成员,直到它再次遇到 Index,此时它输出前一个对象,并开始一个新对象。然后,将最后一个对象添加到数组中,然后就设置好了。然后只需输出到 CSV 或其他。

    $RawData = Get-Content C:\Path\To\input.txt
$Record = ""
$Array = $RawData | Where{$_ -Match "(.+?):(.+)"} | ForEach{If($Matches[1] -eq "Index"){if(![string]::IsNullOrWhiteSpace($Record)){$Record};$Record = [PSCustomObject]@{"Index"=$Matches[2].trim()}}Else{Add-Member -InputObject $Record -MemberType NoteProperty -Name $Matches[1] -Value $Matches[2].trim()}}
$Array += $Record
$Props = $Array | ForEach{$_ | Get-Member -MemberType Properties | Select -Expand Name} | Select -Unique
$Props | Where{($Array[0]|Get-Member -MemberType Properties | Select -Expand Name) -notcontains $_} | ForEach{$Array[0]|Add-Member $_ $null}
$Array | Export-Csv C:\Path\To\File.csv -NoTypeInformation

编辑:我意识到我的第一个答案有一个陷阱,如果第一条记录缺少一个字段(例如,没有姓氏),它将不会为以下任何记录显示该字段。我已经通过从每条记录中获取所有唯一字段的列表并将任何缺失的字段添加到具有空值的第一条记录来纠正这一点。

Edit2:在查看了帕特里克和我的答案后,我意识到他的运行速度要快得多,因此创建了一个结合我们两个答案的修改版本。一些对象创建技术取自他的,行解析取自我的:

$RawData = Get-Content 'C:\temp\input.txt'
$Record = ""
$Array = @()
$Props = $RawData -replace "(.+?):.*","`$1"|select -Unique
ForEach($Line in $RawData){
    $Line -Match "(.+?):(.+)" | Out-Null
    If($Matches[1] -eq "Index"){
        If([string]::IsNullOrEmpty($Array[0])){$Array = @($Record)}else{$Array += $Record}
        $Record = ""|Select -Property $Props
        $Record.Index = $Matches[2].trim()
    }Else{
        $Record.($matches[1]) = $Matches[2].trim()
    }
}
$Array | Export-Csv 'C:\temp\export2.csv' -NoTypeInformation
于 2014-08-22T16:29:58.883 回答