none
String suchen und ersetzen RRS feed

  • Frage

  • Hallo Zusammen,
    ich habe kurz eine Frage im Bezug auf suchen und ersetzen in PowerShell. Ich habe die Datei Test.txt mit dem Folgendem Inhalt:

    1. cn=karl kette, cd=test,; max muster/test;
    2. cn=peter salz, cd=test,; max muster/test;
    3. cn= carlos Pipito, cd=test,; max muster/test;

    Nun sollte in jeder Zeile max muster ersetzt werden durch den namen, damit das File folgendermassen aussieht:

    1. cn=karl kette, cd=test,; karl kette/test;
    2. cn=peter salz, cd=test,; peter salz/test;
    3. cn=carlos Pipito, cd=test,; carlos Pipito/test;

    Für das Suchen und Ersetzten verwende ich folgende Zeile:

    Get-Content"D:\Test.txt"|Foreach-Object{$_.Replace("Alt","Neu")}|Set-Content"D:\Test_Neu.txt"

    Meine Frage nun ist, wie kann ich die Namen in eine Variable speichern?

    Montag, 29. Oktober 2012 10:21

Antworten

  • Hallo,

    steht da auch das "1.","2." und "3." mit davor? Ist das "max muster" immer gleich? Wenn ja, dann könnte man das so machen:

    $nameAlt = "Max Muster"
    get-content "D:\test.txt" | %{
    $nameNeu = $_.substring(6,($_.indexOf(","))
    $_.Replace($nameAlt,$nameNeu)
    } | add-content "D:\test_neu.txt"
    

    ACHTUNG: UNGESTET!

    Eventuell könnte man das noch etwas schöner mit import-csv lösen.

    Viele Grüße

    Frank

     

    -- Frank Röder http://blog.iteach-online.de --

    • Als Antwort markiert PSIE Montag, 29. Oktober 2012 15:20
    Montag, 29. Oktober 2012 13:16
  • Um jeweils "max muster" durch den Namen zu beginn der Zeile zu ersetzen, musst du diesen zuerst extrahieren. Das geht z.b. mit einem Regex-Muster und "select-string -pattern".

    Ich habe als Muster folgendes gewählt "beginnt mit "cn="  und darauf folgend zwei Zeichenblöcken (nur Zeichen a-z) , je mindestens 1 Zeichen und maximal 99, getrennt von einem Leerzeichen".
    Aus dem Ergebnis extrahierst du mit zwei "select" den gefunden String (z.b. "cn=karl kette") und entfernst das "cn=".

    Der Rest ist einfaches replace.

     

     Get-Content "d:\tmp\test.txt" | foreach { $_ -replace ("max muster", ( $_ | Select-String -Pattern "cn=[a-z]{1,99} [a-z ]{1,99}" | select  -expand matches | select -Expand value ).replace("cn=","") ) }
    

     

    Was meinst du mit "in eine Variable speichern"? Was genau? Wie sollen die darin gespeichert sein (z.b.  ein String, per Komma getrennt" oder als Array etc..)

    Grüße, Denniver

     


    Blog: http://bytecookie.wordpress.com

    Hilf mit und markiere hilfreiche Beiträge als "Hilfreich" und Beiträge die deine Frage ganz oder teilweise beantwortet haben als "Antwort".


    Montag, 29. Oktober 2012 13:16
    Moderator
  • Hallo Jungs !

    Lustiger Wettbewerb hier! Da keiner so genau weiß was der PSIE eigentlich will posted jeder mal eine Lösung!

    Ich bin mit RegEx nicht so vertraut deswegen nehme ich (wie Frank) die String Methoden um den String zu bearbeiten.
    Ich nutze hier die String Methoden IndexOf() und Substring() um den Namen aus dem String "herauszuschneiden"
    Anders al Frank nutze ich keine festen Werte für die Substring Positionen, da dies meiner Meinung nach Fehleranfälliger ist als mit IndexOf().

    Das erste IndexOf('=') sucht die Position des ersten Gleichheitszeichen im String, das zweite IndexOf(',') sucht das erste Komma im String. Dann wird in der Methode SubString() mit diesen beiden werten der Substring herausgeschnitten.

    Dokumentation siehe hier:
    http://msdn.microsoft.com/de-de/library/system.string_members%28v=vs.80%29.aspx

    Get-Content "D:\Test.txt" | Foreach-Object {
        $Name = $_.substring($_.IndexOf('=') + 1 ,$_.IndexOf(',') - $_.IndexOf('=') - 1)
        $_.Replace("max muster",$Name)
    } | Set-Content "D:\Test_Neu.txt"


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    • Als Antwort markiert PSIE Montag, 29. Oktober 2012 15:20
    Montag, 29. Oktober 2012 14:05

Alle Antworten

  • Hallo,

    steht da auch das "1.","2." und "3." mit davor? Ist das "max muster" immer gleich? Wenn ja, dann könnte man das so machen:

    $nameAlt = "Max Muster"
    get-content "D:\test.txt" | %{
    $nameNeu = $_.substring(6,($_.indexOf(","))
    $_.Replace($nameAlt,$nameNeu)
    } | add-content "D:\test_neu.txt"
    

    ACHTUNG: UNGESTET!

    Eventuell könnte man das noch etwas schöner mit import-csv lösen.

    Viele Grüße

    Frank

     

    -- Frank Röder http://blog.iteach-online.de --

    • Als Antwort markiert PSIE Montag, 29. Oktober 2012 15:20
    Montag, 29. Oktober 2012 13:16
  • Um jeweils "max muster" durch den Namen zu beginn der Zeile zu ersetzen, musst du diesen zuerst extrahieren. Das geht z.b. mit einem Regex-Muster und "select-string -pattern".

    Ich habe als Muster folgendes gewählt "beginnt mit "cn="  und darauf folgend zwei Zeichenblöcken (nur Zeichen a-z) , je mindestens 1 Zeichen und maximal 99, getrennt von einem Leerzeichen".
    Aus dem Ergebnis extrahierst du mit zwei "select" den gefunden String (z.b. "cn=karl kette") und entfernst das "cn=".

    Der Rest ist einfaches replace.

     

     Get-Content "d:\tmp\test.txt" | foreach { $_ -replace ("max muster", ( $_ | Select-String -Pattern "cn=[a-z]{1,99} [a-z ]{1,99}" | select  -expand matches | select -Expand value ).replace("cn=","") ) }
    

     

    Was meinst du mit "in eine Variable speichern"? Was genau? Wie sollen die darin gespeichert sein (z.b.  ein String, per Komma getrennt" oder als Array etc..)

    Grüße, Denniver

     


    Blog: http://bytecookie.wordpress.com

    Hilf mit und markiere hilfreiche Beiträge als "Hilfreich" und Beiträge die deine Frage ganz oder teilweise beantwortet haben als "Antwort".


    Montag, 29. Oktober 2012 13:16
    Moderator
  • Hallo Jungs !

    Lustiger Wettbewerb hier! Da keiner so genau weiß was der PSIE eigentlich will posted jeder mal eine Lösung!

    Ich bin mit RegEx nicht so vertraut deswegen nehme ich (wie Frank) die String Methoden um den String zu bearbeiten.
    Ich nutze hier die String Methoden IndexOf() und Substring() um den Namen aus dem String "herauszuschneiden"
    Anders al Frank nutze ich keine festen Werte für die Substring Positionen, da dies meiner Meinung nach Fehleranfälliger ist als mit IndexOf().

    Das erste IndexOf('=') sucht die Position des ersten Gleichheitszeichen im String, das zweite IndexOf(',') sucht das erste Komma im String. Dann wird in der Methode SubString() mit diesen beiden werten der Substring herausgeschnitten.

    Dokumentation siehe hier:
    http://msdn.microsoft.com/de-de/library/system.string_members%28v=vs.80%29.aspx

    Get-Content "D:\Test.txt" | Foreach-Object {
        $Name = $_.substring($_.IndexOf('=') + 1 ,$_.IndexOf(',') - $_.IndexOf('=') - 1)
        $_.Replace("max muster",$Name)
    } | Set-Content "D:\Test_Neu.txt"


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    • Als Antwort markiert PSIE Montag, 29. Oktober 2012 15:20
    Montag, 29. Oktober 2012 14:05
  • Ja Regex ist leider nicht einfach zugänglich, aber wenn man mal drin ist, möchte mans nicht mehr missen. Es gibt keinen besseren Weg Strings exakt zu beschreiben.

    An dieser Stelle kann ich nur mal wieder die Bücher von Tobias Weltner empfehlen, er erklärt da (u.a.) Regex sehr einfach und anschaulich.

     

    Grüße, Denniver


    Blog: http://bytecookie.wordpress.com

    Hilf mit und markiere hilfreiche Beiträge als "Hilfreich" und Beiträge die deine Frage ganz oder teilweise beantwortet haben als "Antwort".

    Montag, 29. Oktober 2012 14:17
    Moderator
  • @Denniver

    Ich Programmiere nun schon seit 20 Jahren und genau so lange drücke ich mich um RegEx herum.
    Ich muss sagen ich hab´s bisher auch immer anders gelöst bekommen. ;-))
    Aber du hast schon recht, da muss ich mal ran. Tobias hat das ja auch in seinem Offenen Buch:
    http://powershell.com/cs/blogs/ebookv2/archive/2012/03/06/chapter-13-text-and-regular-expressions.aspx#regular-expressions

    Ich hatte erst diesen Ansatz, wusste aber nicht wie ich das Gleichheitszeichen und das Komma (einfach) wegbekomme:

    $Test = 'cn=karl kette, cd=test,; max muster/test;'
    [RegEx]::Match($Test,'=.*?,').value
    @Frank

    Ich glaube deine Substring() Berechnung, rechnet falsch, da der zweite Integer wert die Länge des String von der Startposition aus berechnen muss!
    http://msdn.microsoft.com/de-de/library/aka44szs%28v=vs.80%29.aspx


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    Dienstag, 30. Oktober 2012 06:24
  • Hallo Peter,

    recht haste....Das muss natürlich so aussehen:

    $nameNeu = $_.substring(6,($_.indexOf(",")-6)

    Deine Variante ist natürlich universeller.

    Viele Grüße

    Frank


    -- Frank Röder http://blog.iteach-online.de --

    Dienstag, 30. Oktober 2012 11:22