kaffeepause
Goto Top

PowerShell, Text zwischen zwei Strings ersetzen

Hallo,

ich komme mit PowerShell leider noch nicht so gut zurecht und brauche daher eure Hilfe.

Bei uns wird etwas aus dem AD exportiert und an anderer Stelle importiert. Beim Export wird eine Textdatei erzeugt, die dann geändert werden muss. Konkret muss immer alles geändert werden, was mit "OU=" anfängt und mit "DC=intern" aufhört (einschließlich der genannten Zeichen).

Beispieldatensatz:
dn: CN=Mustermensch\, Maxi,OU=Benutzer,OU=Berlin,DC=firma,DC=intern
changetype: add
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: Mustermensch, Maxi
sn: Mustermensch
l: Berlin
st: Rheinland-Pfalz
postalCode: 08151
telephoneNumber: +49 (0815) 12345 - 67
givenName: Maxi
company: Firma
streetAddress:: Hauptstr
wWWHomePage: https://www.firma.de/
mail: Maxi.Mustermensch@firma.de

Daraus soll entstehen:
CN=Mustermensch\, Maxi,OU=Kontakte,DC=transfer,DC=local
changetype: add
objectClass: top
...

Der Pfad (hier im Beispiel "OU=Benutzer,OU=Berlin,") kann sich ändern, es kann auch "Moskau", "London" oder sonst was sein. Es könnte auch statt "Benutzer" "OU=Deaktivierte,OU=Benutzer" oder weitere Verschachtelungen stehen.

Bisher habe ich mit Replace gearbeitet, aber da muss ich das, was ich ersetzen will exakt eingeben; wird irgendeine Änderung durchgeführt, passt das Skript nicht mehr:
(Get-Content C:\Import.ldf) | ForEach-Object { $_ -replace "OU=Benutzer,OU=Berlin,DC=firma,DC=intern", "OU=Kontakte,DC=transfer,DC=local" } | Set-Content C:\ImportEdit.ldf  
In meinem bisherigen Skript sind also zig Zeilen, mit deren Hilfe ich versuche jeden möglichen Fall abzufangen.

Sinnvoller wäre daher ein Skript, das in etwa so wäre:
Suche mir den String, der mit "CN=" anfängt und mit "DC=intern" aufhört. Ersetze diesen String durch "OU=Kontakte,DC=transfer,DC=local".

Ich bin schon eine ganze Weile am googeln, es gibt auch einige, die ein ähnliches Problem haben, aber ich krieg es nicht so umgesetzt, dass es bei mir funktioniert.

Kann mir jemand behilflich sein?

PS: Die Textdatei enthält natürlich nicht nur einen solchen Datensatz, sondern mehrere.

Viele Grüße,

Content-ID: 519010

Url: https://administrator.de/forum/powershell-text-zwischen-zwei-strings-ersetzen-519010.html

Ausgedruckt am: 23.12.2024 um 16:12 Uhr

141965
Lösung 141965 26.11.2019 aktualisiert um 13:00:51 Uhr
Goto Top
Bisher habe ich mit Replace gearbeitet, aber da muss ich das, was ich ersetzen will exakt eingeben;
Nein musst du nicht, -replace arbeitet mit Regular Expressions und für die ist das ein Kinderspiel face-wink
(gc  'C:\Import.ldf') -replace '(^dn:\s*CN=.*?)(?=,OU=).*','$1,OU=Kontakte,DC=transfer,DC=local' | sc ' C:\Import.ldf'
Kaffeepause
Kaffeepause 26.11.2019 um 13:07:01 Uhr
Goto Top
Boah, das war schnell!...

Ja, super. Funktioniert. Vielen Dank!

Muss ich mir jetzt nur noch mal in Ruhe anschauen, weil ich die Regular Expressions noch nicht auf Deutsch übersetzen kann.
Ja, die Regular Expressions sind für mich im Moment noch proper Chinesisch...
Aber das ist jetzt nicht das Problem.

Also, vielen lieben Dank für die Lösung!
Kaffeepause
Kaffeepause 26.11.2019 um 13:24:44 Uhr
Goto Top
Nur zum Verständnis:
du verwendest keinen String, der das Ende ermittelt, weil nach dem Ende sowieso nichts mehr kommt, was man berücksichtigten müsste, richtig?
Also du gibst nur den Anfang mit (Suche mir alles, was so und so anfängt)
141965
Lösung 141965 26.11.2019 aktualisiert um 14:07:12 Uhr
Goto Top
(^dn:\s*CN=.*?)
Das sucht am Zeilenanfang(^) nach dem String "dn:" mit folgenden nicht zwingendem Leerzeichen, worauf der String "CN=" gefolgt von beliebigen Zeichen (non greedy (?)) kommen kann. Das ganze Konstrukt speichern wir durch die umschließenden Klammern in einem Submatch den wir hinterher im Replacement mit $ und der entsprechenden Submatch Nummer ansprechen können

(?=,OU=).
Dieses Konstrukt nennt sich Positive Lookahead und sucht nach dem ersten Auftreten des Strings ",OU=" der als Begrenzer zum CN dient.
.*
Das matcht den Rest der Zeile der soll ja sowieso komplett ersetzt werden


Der Replacement-String:

$1,OU=Kontakte,DC=transfer,DC=local

... baut aus dem ersten Submatch des Regex (erstes Klammerpaar) und dem festen String das Replacement des Regex zusammen.
Kaffeepause
Kaffeepause 26.11.2019 um 14:22:11 Uhr
Goto Top
Danke! Ja, habe ich kapiert face-smile
Schönen Tag noch!