从垂直到水平动态枚举对象

时间:2018-10-14 16:53:56

标签: powershell

我已经使用PowerShell将数据放入一个对象,如下所示,现在我想将其从垂直转换为水平。 (类似于Excel中的“文本到列”功能)。如何动态枚举“所有第1行”作为对象标头,其余的将分配给其子项?

输入文件在PSObject中包含“行”,“列”和“文本”三列

PS > $table

Row Column Text
--- ------ ----
  1      1 Dept
  1      2 Time
  1      3 Day1
  1      4 Day2
  1      5 Day3
  1      6 Day4
  1      7 Day5
  1      8 Day6
  1      9 Day7
  2      1 Marketing
  2      2 11:00
  2      3 4
  2      4 8
  2      5 8
  2      6 8
  2      7 4
  2      8 0
  2      9 0
  3      1 Finance
  3      2 09:00
  3      3 4
  3      4 8
  3      5 8
  3      6 8
  3      7 4
  3      8 0
  3      9 0

我试图使用以下代码将其分配给另一个对象,但我不知道如何让内容放入。

$data = New-Object –TypeName PSObject

$table | %{
    if ($_.row -eq 1) {
        $data | Add-Member –MemberType NoteProperty –Name $_.text –Value ''
    } 
}

输出:

PS > $data|ft

Dept Time Day1 Day2 Day3 Day4 Day5 Day6 Day7
---- ---- ---- ---- ---- ---- ---- ---- ----

预期结果:

Dept      Time  Day1 Day2 Day3 Day4 Day5 Day6 Day7 
----      ----  ---- ---- ---- ---- ---- ---- ----
Marketing 11:00 4    8    8    8    4    0    0
Finance   09:00 4    8    8    8    4    0    0

1 个答案:

答案 0 :(得分:1)

需要某种间接引用。您可以执行以下操作:

$dataLabels = New-Object –TypeName psobject
$dataZero   = New-Object –TypeName psobject
$data       = @()        ### or ### New-Object System.Collections.ArrayList
$table | Where-Object { $_.row -eq 1 } | ForEach-Object {
    $dataLabels | 
      Add-Member –MemberType NoteProperty –Name $_.Column –Value $_.Text
    $dataZero | 
      Add-Member –MemberType NoteProperty –Name $_.Text   –Value ''
  }
$dataZeroCsv = $dataZero | ConvertTo-Csv -NoTypeInformation
for ( $i=0;$i -lt ($Table.Row|Measure-Object -Maximum).Maximum -1;$i++)
{
    $dataLine = $dataZeroCsv | ConvertFrom-Csv
    $table | Where-Object { ($_.Row - 2) -eq $i } | 
        ForEach-Object {
           $dataLine.($dataLabels.($_.Column)) = $_.Text ### indirect reference
        }
    $data += $dataLine   ### or ### [void]$data.Add( $dataLine )
}

## Output:
$data | Format-Table

假设$table的定义如下:

$tableArr = @"
Row Column Text
  1      1 Dept
  1      2 Time
  1      3 Day1
  1      4 Day2
  1      5 Day3
  1      6 Day4
  1      7 Day5
  1      8 Day6
  1      9 Day7
  2      1 Marketing
  2      2 11:00
  2      3 4
  2      4 8
  2      5 8
  2      6 8
  2      7 4
  2      8 0
  2      9 0
  3      1 Finance
  3      2 09:00
  3      3 3
  3      4 4
  3      5 5
  3      6 6
  3      7 7
  3      8 0
  3      9 1
  4      1 TestDept
  4      2 16:00
  4      4 5
"@  -split [System.Environment]::NewLine
$table = $tableArr -replace '\s+', ' ' -replace '^\s', '' | 
            ConvertFrom-Csv -Delimiter ' '

输出

PS D:\PShell> D:\PShell\SO\52804963.ps1

Dept      Time  Day1 Day2 Day3 Day4 Day5 Day6 Day7
----      ----  ---- ---- ---- ---- ---- ---- ----
Marketing 11:00 4    8    8    8    4    0    0
Finance   09:00 3    4    5    6    7    0    1
TestDept  16:00      5