2017-08-28 5 views
2

Ich habe eine Textdatei, die ich lese und ich muss die Werte von bekommen.String trim und split

Beispiel Textdatei:

 
[Site 01] 
DBServer=LocalHost 
DBName=Database01 
Username=admin 
Password=qwerty 

[Site 02] 
DBServer=192.168.0.10 
DBName=Database02 
Username=admin 
Password=qwerty 

Derzeit mein Code der Datei durchliest und legt für jede Zeile jeder jeweils als Array-Eintrag DBServer=, die gefunden wird und diese Textdatei viele Seiten haben kann:

$NumOfSites = Get-Content $Sites | 
       Select-String -Pattern "DBServer=" -Context 0,3 
$i = 0 
$NumOfSites | ForEach-Object { 
    $svr = $NumOfSites[$i] -isplit "\n" | 
      % { ($_ -isplit 'DBServer=').Trim()[1] } 
    $db = $NumOfSites[$i] -isplit "\n" | 
      % { ($_ -isplit 'DBName='.Trim())[1] } 
    $uid = $NumOfSites[$i] -isplit "\n" | 
      % { ($_ -isplit 'Username='.Trim())[1] } 
    $pswd = $NumOfSites[$i] -isplit "\n" | 
      % { ($_ -isplit 'Password='.Trim())[1] } 
    $i = $i+1 
} 

Ich kann nicht jedes Attribut richtig ohne einige zusätzliche Leerzeichen oder etwas schön wie eine String-Variable zu trennen. Ich muss nur die Informationen extrahieren, um sie in eine SQL-Verbindungslinie als Variablen aus dem Format des Dateibeispiels zu setzen, das ich habe.

+1

Der von Ihnen gepostete Code ist unvollständig. Bitte stelle sicher, dass dein Code ein [mcve] ist, wenn du eine Frage stellst. Außerdem scheinen einige der Klammern falsch zu sein, obwohl das den Code nicht brechen sollte. Das Analysieren von INI-Dateien ist ein ziemlich gut gelöstes Problem. Bitte machen Sie einige [Forschung] (https://stackoverflow.com/search?q=%5Bpowershell%5D+parse+ini). –

Antwort

3

Anders als die Satzköpfe (dh [Site 01]) kann der Rest von ConvertFrom-StringData gehandhabt werden nur fein. Wir können die Datensätze einfach in Objekte konvertieren, die sich mehr oder weniger direkt in der Kopfzeile aufteilen. ConvertFrom-StringData verwandelt eine mehrzeilige Zeichenkette in eine Hashtabelle, und Sie können das einfach als [PSCustomObject] und Viola, Sie haben Objekte, die einfach zu bedienen sind.

$NumOfSites = Get-Content $Sites -raw 
$SiteObjects = $NumOfSites -split '\[.+?\]'|%{[PSCustomObject](ConvertFrom-StringData -StringData $_)} 

Dann können Sie $SiteObjects manipulieren aber Sie fit (Ausgabe CSV, wenn Sie wollen, oder Filter auf jede Eigenschaft mit Select-Object) zu sehen. Oder, wenn Sie suchen Verbindungen, die Sie durchlaufen kann sie machen den Aufbau Ihrer Verbindungen je nach Bedarf ...

ForEach($Connection in $SiteObjects){ 
    $ConStr = "Server = {0}; Database = {1}; Integrated Security = False; User ID = {2}; Password = {3};" -f $Connection.DBServer.Trim(), $Connection.DBName.Trim(), $Connection.Username.Trim(), $Connection.Password.Trim() 
    <Do stuff with SQL> 
} 

Edit: aktualisiert meine Antwort, da der Beispieltext geändert wurde <pre> und </pre> hinzuzufügen. Wir müssen diese nur entfernen, und da das OP Fehler über Methoden für Nullwerte erhält, werden wir auch nach Null filtern.

$NumOfSites = Get-Content $Sites -raw 
$SiteObjects = $NumOfSites -replace '<.*?>' -split '\[.+?\]' | ?{$_} |%{[PSCustomObject](ConvertFrom-StringData -StringData $_)} 
ForEach($Connection in $SiteObjects){ 
    $svr = $Connection.DBServer.Trim() 
    $db = $Connection.DBName.Trim() 
    $uid = $Connection.Username.Trim() 
    $pwd = $Connection.Password.Trim() 
} 
+0

Hier war diese nette Idee +1 benötigt den '-raw' Parameter für die GC. – LotPings

+0

Ah, ja, ich habe die Antwort aktualisiert, um den '-raw'-Schalter für 'Get-Content' einzuschließen. Danke, dass du mich daran erinnert hast. – TheMadTechnician

+0

Ich habe dies versucht, aber es sems nur füllen die $ Connection var nach der ersten Runde und ich bekomme Fehler über Sie können eine Methode auf einen nullwertigen Ausdruck nicht aufrufen. – catalyph

1

Hier ist ein Vorschlag, wenn Sie nur über das Erhalten der Wert nach dem Gleichheits Pflege:

Get-Content Example.txt | 
    ForEach-Object { 
     Switch -Regex ($_) { 
      'dbs.+=' { $svr = ($_ -replace '.+=').Trim() 
      .. etc .. 
     } 
    } 

Get-Content verrohrt bis ForEach-Object wird jede Zeile als ein eigenes Objekt interpretieren.


Edit:
Sie wurden dort die meisten der Art und Weise, aber es ist nicht notwendig, -split die Linien

$NumOfSites = Get-Content $Sites | Select-String -pattern "DBServer=" -Context 0,3 
$NumOfSites | ForEach-Object { 
    Switch -Wildcard ($_) { 
     'DBS*=' { $svr = ($_ -replace '.+=').Trim() } 
     'DBN*=' { $db = ($_ -replace '.+=').Trim() } 
     'U*=' { $uid = ($_ -replace '.+=').Trim() } 
     'P*=' { $pw = ($_ -replace '.+=').Trim() } 
    } 
} 
+0

Dies erfasst die ersten Site-Variablen, behält sie dann aber bei, und sie haben sich bei der nächsten Loop-Rückgabe nicht geändert. – catalyph