2017-07-26 26 views
0

我有一个数据集,看起来像下面PowerShell的转置,只保留一组头

headers   data 
ip     192.168.1.1 
netmask   255.255.255.0 
description  class C 
ip     172.20.1.1 
netmask   255.255.0.0 
description  class B 
ip     10.0.0.1 
netmask   255.255.255.0 
description  class A 

我怎样才能把它转换成我的预期的输出:

ip   netmask   description 
192.168.1.1 255.255.255.0 class C 
172.20.1.1 255.255.0.0  class B 
10.0.0.1  255.0.0.0  class A 

目前我进口这个数据来自CSV如下:

$data = import-csv .\data.txt -headers headers,data 

如果有一个简单的方法来做到这一点,在Excel中,这将是太棒了。

任何协助将是伟大的。谢谢。

回答

1

上一个答案没有使用问题中指定的数据,这是一个问题。它也完全评论说明它的作用。下面的代码是如何工作的一个概要:

$newrow = @{} # newrow contains the values on an output row at any given time 
$newtable = [System.Collections.ArrayList]@() # newtable contains the final output 

# Loop through each row in the input data, assign oldrow to the current row 
foreach($oldrow in $data) { 
    # If the output row already has an ip, netmask or description, then start a new row (hashtable) and add the current row (hashtable) to output 
    if ($newrow[$oldrow.headers] -ne $null) { 
     Write-Host "$($oldrow.headers) Already found. Adding new row to output" -ForegroundColor Green 
     # Add the current row to the target object 
     [void]$newtable.Add($(New-Object PSObject -Property $newrow)) 
     # Create a new empty row (hashtable) 
     $newrow = @{} 
    } 
    # For each iteration, keep adding data 
    Write-Host "Adding new entry for $($oldrow.headers)" 
    $newrow[$oldrow.headers] = $oldrow.data 
} 

# The final row is not added to the table within the loop, so it must be added here 
Write-Host "Loop finished, adding final row to output" -ForegroundColor Green 
[void]$newtable.Add($(New-Object PSObject -Property $newrow)) 

$newtable | select ip,netmask,description 

假设

当遇到同一个header值的记录,需要一个新的行。在此之前,应将记录添加到同一行,并且标题值提供新的列名称。

过程

  1. 成立了一家名为$ NEWROW哈希表。
  2. 设置一个名为$ newtable的ArrayList。 ArrayLists比标准数组更灵活,因为它们有Add()方法。
  3. 使用foreach循环遍历数据
  4. 从if语句开始,该语句处理查找带有已分配列的记录。此时使用Write-Host发送消息,添加旧行并设置新行。在foreach循环的第一次迭代中,由于散列表为空,它总是计算为false。
    1. if条件之外的块中,不断向散列表中添加值。
    2. 最后,添加最后一行,然后使用select-object以正确的顺序打印输出。
+0

这工作完美无瑕。谢谢! – johnnyb

1

#IMPORT数据

$data = Import-Csv .\data.txt -headers headers,data 
$data | FT -AutoSize 

#Remove第一行

get-content $data | select -Skip 1 | set-content "$data-temp" 
move "$data-temp" $data -Force 

#Convert表

$Duration = Measure-Command { 
    $b = @() 
    foreach ($Property in $data.Property | Select -Unique) { 
     $Props = [ordered]@{ Property = $Property } 
     foreach ($Server in $data.Server | Select -Unique){ 
      $Value = ($data.where({ $_.Server -eq $Server -and 
         $_.Property -eq $Property })).Value 
      $Props += @{ $Server = $Value } 
     } 
     $b += New-Object -TypeName PSObject -Property $Props 
    } 
} 

Write-Host "Finished transposing " -ForegroundColor Green -NoNewline 
Write-Host "$(($data | Get-Member -MemberType Properties).count)/$($data.Count)" -ForegroundColor Yellow -NoNewline 
Write-Host " columns/rows into " -ForegroundColor Green -NoNewline 
Write-Host "$(($b | Get-Member -MemberType Properties).count)/$($b.Count)" -ForegroundColor Yellow -NoNewline 
Write-Host " columns/rows in " -ForegroundColor Green -NoNewline 
Write-Host $Duration.Milliseconds -ForegroundColor Yellow -NoNewline 
Write-Host " Milliseconds" -ForegroundColor Green 

$b | FT -AutoSize 
$b | Out-GridView 
$b | Export-Csv .\newData.csv -NoTypeInformation 

newData.cs v应该看起来像你所期望的,如果没有,让我再次知道。

+0

您是否使用问题中提供的输入数据对此进行了测试? – mjsqu

+0

@mjsqu,no。现在,我在我的Ubuntu笔记本电脑上。 –