2017-07-26 25 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筆記本電腦上。 –