2016-04-20 4 views
1

Ich habe einen Befehl, den ich auf PowerShell 2.0 ausgeführt habe, die mir die Ausgabe unten gibt.PowerShell: Pull-Tabelle von einer Zeichenfolge

PowerShell Output

Alles im Screenshot oben ist ein Riesen-String. Ich möchte den Tabellenteil des Strings herausziehen, damit ich ihn als Liste formatieren kann. Letztlich will ich die Ausgabe aussehen:

INSTANCE_NAME: Sample Name 
STATUS: MOUNTED 
DATABASE_STATUS: ACTIVE 

Mein erster Gedanke ist die Verwendung Regex war den Tisch zu ziehen. Ich dachte, so etwas könnte funktionieren, aber bisher war ich nicht erfolgreich.

$tabletext = [regex]::match($rawtext, "(INSTANCE_NAME(.+\r\n)+)") 

EDIT: Hier ist der Text als String zurück.

SQL*Plus: Release 12.1.0.1.0 Production on Wed Apr 20 16:34:57 2016 

Copyright (c) 1982, 2013, Oracle. All rights reserved. 


Connected to: 
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options 

SQL> 
INSTANCE_NAME STATUS  DATABASE_STATUS 
---------------- ------------ ----------------- 
sample_name  OPEN   ACTIVE 

SQL> Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options 
+0

Können Sie den Text auch als Zeichenfolge bereitstellen (damit könnte man herumspielen)? – Jan

+1

Haben Sie in PowerShell 5.0 das Beispiel-basierte Parsen probiert? –

+0

Ich habe nicht. Entschuldigung, ich hätte erwähnen sollen, dass ich auf PowerShell 2.0 beschränkt bin. – eltaco431

Antwort

2

Ich habe etwas sehr ähnliches getan, um Firebird sql Ausgabe zu analysieren.

Hier ist ein Skript, das auf dem Beispieldaten funktioniert:

function parse-headers($lines) { 
    $h = $lines[0] 

    $headers = $h.Split(" ", [System.StringSplitOptions]::RemoveEmptyEntries) 
    $headers = $headers | % { 
     new-object pscustomobject -property @{ 
      Length = $_.Length 
      Offset = $h.IndexOf($_) 
      Text = $_ 
      } 
    }  
    for($i = 1; $i -lt $headers.length; $i++) { 
     $headers[$i-1].Length = $headers[$i].Offset - $headers[$i-1].Offset - 1 
    } 
    $headers[$header.length-1].Length = $h.length - $headers[$header.length-1].Offset 

    return $headers 
} 

function parse-sqloutput($lines) { 
    $headers = parse-headers $lines 
    $result = @() 

    for($l = 2; $l -lt $lines.Length; $l++) { 
     $line = $lines[$l] 
     $headernames = $headers | % { $h = @{} } { $h[$_.Text] = $null } { $h } 
     $r = New-Object -type pscustomobject -Property $headernames 
     for($i = 0; $i -lt $headers.length; $i++) { 
      try { 
       $h = $headers[$i] 
       $name = $h.text 
       if ($i -eq $headers.length - 1) { 
        $value = $line.Substring($h.Offset).Trim() 
       } 
       else { 
        $value = $line.Substring($h.Offset, $h.Length).Trim() 
       } 
       $r.$name = $value 
      } catch { 
       Write-Warning "failed to parse line $l col $i" 
       throw  
      } 
     } 
     $result += $r 
    } 
    return $result 
} 

function get-sqltable($sqlout) { 

    #find sql table output 
    $startidx = -1 
    $endidx = -1 

    for($i = 0; $i -lt $sqlout.Length; $i++) { 
     $line = $sqlout[$i] 
     if ($line -match "^\s*([\-]+\s*)+$") { 
      $startidx = $i - 1 
     } 
     if ($startidx -ge 0 -and $line -match "^\s*$") { 
      $endidx = $i 
     } 
     if ($startidx -ge 0 -and $endidx -ge 0) { break } 
    } 

    $sqlout = $sqlout | select -Skip $startidx -First ($endidx-$startidx) 
    return $sqlout 
} 

$sqlout = get-content "sqlout.txt" | out-string 

#split giant string into lines 
$sqlout = $sqlout | Split-String "`r`n" 
$sqlout = get-sqltable $sqlout 

#we should now have only sql table in $sqlout 
$result = parse-sqloutput $sqlout 

$result | Format-List 

Die Idee ist:

  1. eine Linie finden, die nur Zeichenfolgen von - Zeichen enthält und annehmen, dass es Kopfzeile markiert.
  2. Suchen Sie nach der ersten Zeile nach der Kopfzeile und nehmen Sie an, dass es das Ende der Tabellenausgabe ist.
  3. Analysieren Sie die Kopfzeile, erhalten Sie die Namen und Längen der Spalten.
  4. Werte basierend auf analysierten Spaltenlängen abrufen.
+1

Es sieht bei PowerShell V4 und niedriger so aus, dass Split-String kein Standard-Cmdlet ist. Wenn Sie die standardmäßigen PowerShell-Befehle verwenden, können Sie denselben Befehl ausführen und dasselbe Ergebnis erzielen, wenn Sie $ sqlout = $ sqlout | Split-String "' r'n "durch" $ sqlout = $ sqlout -split "' r ersetzen 'n" –

+0

Aus irgendeinem Grund fehlen mir Zeichen in der Ausgabe und einige der Charaktere sind verlegt. Ich werde das ein bisschen mehr untersuchen müssen. Ich werde dies als die Antwort markieren, sobald ich herausfinden, warum meine Ausgabe ist verstümmelt. Danke! – eltaco431