2012-02-03 40 views
2

我正在解析磁盤陣列中的文本輸出,該文件以可預測的格式列出有關LUN快照的信息。在嘗試其他方式以可用的方式從數組中獲取這些數據後,我唯一能做的就是生成這個文本文件並解析它。輸出如下所示:Powershell中的文本分析:識別目標行並解析下一個X行以創建對象

SnapView logical unit name: deleted_for_security_reasons 
SnapView logical unit ID: 60:06:01:60:52:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX 
Target Logical Unit: 291 
State: Inactive 

這將在每個組之間用一個換行符重複所有文件。我想識別一個組,解析四行中的每一行,創建一個新的PSObject,將每行的值作爲新的NoteProperty添加,然後將新對象添加到集合中。

我能弄清楚的是,一旦我確定了四行代碼塊中的第一行,然後如何處理第二行,第三行和第四行的文本。我遍歷每一行,找到一個塊的開始,然後處理它。這裏是我到目前爲止,有評論那裏魔高一尺:

$snaps = get-content C:\powershell\snaplist.txt 
$snapObjects = @() 

foreach ($line in $snaps) 
    { 

     if ([regex]::ismatch($line,"SnapView logical unit name")) 
     { 
      $snapObject = new-object system.Management.Automation.PSObject 
      $snapObject | add-member -membertype noteproperty -name "SnapName" -value $line.replace("SnapView logical unit name: ","") 
      #Go to the next line and add the UID 
      #Go to the next line and add the TLU 
      #Go to the next line and add the State 
      $snapObjects += $snapObject 
     } 
} 

我已經走遍了谷歌和StackOverflow上試圖找出我怎麼可以參考我通過迭代對象的行號,和我無法弄清楚。我可能過多地依賴於foreach循環,所以這影響了我的思維,我不知道。

回答

4

正如你所說,我認爲你在想太多foreach當你應該想到。下面的修改應沿的線條更你要找的東西:

$snaps = get-content C:\powershell\snaplist.txt 
$snapObjects = @() 

for ($i = 0; $i -lt $snaps.length; $i++) 
    { 
     if ([regex]::ismatch($snaps[$i],"SnapView logical unit name")) 
     { 
      $snapObject = new-object system.Management.Automation.PSObject 
      $snapObject | add-member -membertype noteproperty -name "SnapName" -value ($snaps[$i]).replace("SnapView logical unit name: ","") 
      # $snaps[$i+1] Go to the next line and add the UID 
      # $snaps[$i+2] Go to the next line and add the TLU 
      # $snaps[$i+3] Go to the next line and add the State 
      $snapObjects += $snapObject 
     } 
} 

while循環可能是更清潔,因爲這樣你可以通過$ 4,而不是1,當你打這種情況下增加我,但因爲其他三條線不會觸發「如果」聲明......沒有危險,只有幾個浪費的週期。

+0

謝謝,我會試試這個,現在!多謝。更新:像魅力一樣工作,你也教會了我一些東西。謝謝! – Formica 2012-02-04 00:07:13

+0

難道你不能在for循環中增加$ i嗎? – mthomas 2015-07-24 13:28:50

0

另一種可能性

function Get-Data { 
    $foreach.MoveNext() | Out-Null 
    $null, $returnValue = $foreach.Current.Split(":") 

    $returnValue 
} 

foreach($line in (Get-Content "C:\test.dat")) { 

    if($line -match "SnapView logical unit name") { 
     $null, $Name = $line.Split(":") 
     $ID = Get-Data 
     $Unit = Get-Data 
     $State = Get-Data 

     New-Object PSObject -Property @{ 
      Name = $Name.Trim() 
      ID = ($ID -join ":").Trim() 
      Unit = $Unit.Trim() 
      State = $State.Trim() 
     } 
    } 
} 

Name       ID            Unit State 
----       --            ---- ----- 
deleted_for_security_reasons 60:06:01:60:52:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX 291 Inactive 
0
switch -regex -file C:\powershell\snaplist.txt { 
'^.+me:\s+(\S*)' {$SnapName = $Matches[1]} 
'^.+ID:\s+(\S*)' {$UID = $Matches[1]} 
'^.+it:\s+(\S*)' {$TLU = $Matches[1]} 
'^.+te:\s+(\S*)' { 
    New-Object PSObject -Property @{ 
    SnapName = $SnapName 
    UID = $UID 
    TLU = $TLU 
    State = $Matches[1] 
    } 
} 
} 
0

試試這個

Get-Content "c:\temp\test.txt" | ConvertFrom-String -Delimiter ": " -PropertyNames Intitule, Value 

如果你有多個包試試這個

[email protected]" 
{Data:SnapView logical unit name: {UnitName:reasons} 
SnapView logical unit ID: {UnitId:12:3456:Zz} 
Target Logical Unit: {Target:123456789} 
State: {State:A State}} 
"@ 


Get-Content "c:\temp\test.txt" | ConvertFrom-String -TemplateContent $template | % { 
    [pscustomobject]@{ 
    UnitName=$_.Data.UnitName 
    UnitId=$_.Data.UnitId 
    Target=$_.Data.Target 
    State=$_.Data.State 
    } 
} 
相關問題