none
Bestimmte Werte aus Textdatei in eine Variable schreiben RRS feed

  • Frage

  • Moin liebe Community,

    ich brauche Hilfe bei einem Script das ich grade schreibe und zur Zeit hänge ich übelst auf dem Schlauch.
    Die Situation:

    Für ein Projekt (Temperaturmessung) benötige ich festgelegte "Treshold"-Werte, anhand derer das Skript merkt, wenn die Temperatur zu hoch ist und somit eine Nachricht an die zuständigen Leute schickt.
    Die Treshold-Werte befinden sich in einer Textdatei mit anderen zusätzlichen Infos (ganz einfach dargestellt), sodass auch andere diese Werte noch für Ihre Niederlassungen festlegen können.f

    Nun versuche ich über Powershell lediglich die Treshold-Werte einzulesen, damit ich damit Arbeiten kann.
    Das ganze soll natürlich dauerhaft laufen und im laufenden Betrieb überprüfen, ob eine neue Zeile hinzu kam.
    Für jeden Treshold Wert - also einen Standort - ist dann eine Überprüfung vorgesehen.

    Ich bin so gut wie fertig, bis auf diese Feinheiten.
    Unten habe ich mal den Anfang meines Skriptes eingefügt. Die Treshold-Werte sollen dann dynamisch in die Arrays eingefügt werden ($Warnmeldungen[log.Basename][TempTresHold])

    $LogQuelle = "C:\Users\XXXX\Desktop\Projekt_XXXX\Projekt_Scripte\Finale_Versionen"
    $logs = Get-ChildItem $LogQuelle -Filter *.log
    
    
    
    $Warnmeldungen=@{}
    foreach ($log in $logs)
    {
        if (!($Warnmeldungen[$log.BaseName]))
        {
            $Warnmeldungen[$log.BaseName] = @{}
            $Warnmeldungen[$log.BaseName]["DateTimeFirstWarning"] = ""
            $Warnmeldungen[$log.BaseName]["LastWarningInterval"] = 0
            $Warnmeldungen[$log.BaseName]["LastTemperaturLevel"] = 0
            $Warnmeldungen[$log.BaseName]["TempTreshold1"] = #Wert den ich aus der Textdatei übernehme#
            $Warnmeldungen[$log.BaseName]["TempTreshold2"] = #Wert den ich aus der Textdatei übernehme#
            $Warnmeldungen[$log.BaseName]["TempTreshold3"] = #Wert den ich aus der Textdatei übernehme#
        }
    }

    Ich hoffe das ihr mir weiterhelfen könnt.

    Gruß

    Klotschek



    Donnerstag, 26. März 2015 13:52

Antworten

  • Hallo Klotschek!

    Ich kann da leider kein ordentlich strukturierter Text erkennen, man könnte das als CSV verarbeiten wenn das ternnzeichen der einzelnen Spalten immer gleich ist und nicht im Text einer Spalte vorkommt.

    Deshalb machen wir das mit dem so genannten Text-Parsing und wir schreiben den Code so, damit er den Text parst.
    Ein Parser wird dazu verwendet, einen Text in eine neue Struktur zu übersetzen oder Daten aus dem Text zu extrahieren. Der Programmierer von dem Parser versucht in dem Text die Struktur zu erkennen und diese Struktur in einen Code umzusetzen. Das Ergebnis sollte bei der PowerShell immer ein Objekt sein das die Daten in Name = Wert paaren enthält.

    Parsen von unstrukturiertem Text ist leider oft sehr fehleranfällig und sollte die letzte aller Optionen sein.

    Get-Content liest eine Textdatei Zeile für Zeile ein und gibt die Zeile dann in die Pipeline. Nun kann man für jede Zeile (for each) einen Code ausführen lassen.

    Text kann man in PowerShell mit Hilfe der .NET Methoden von der Klasse System.String verarbeiten oder mit “Regulären Ausdrücken” oder Englisch: Regular Expression.
    Weil der Name “Regular Expressions” etwas unhandlich ist, werden diese Kurz auch “RegEx” genannt.

    # Aus jeder Zeile von der Datei wird ein echtes Objekt extrahiert
    Get-Content "C:\Pfad\zur\Datei.txt" | ForEach-Object {
      # Das Aktuelle Objekt (die Zeile), das in der Pipeline ist ist in der Automatischen Variable $_ 
        
      # Variable in andere Variable übertragen und Leerzeichen an den Enden entfernen
      $Zeile = ($_).Trim()
    
      # IPv4 Adresse mit Regex aus der Zeile holen
      # Wenn die Zeile mit einer IPv4 beginnt wird sie verarbeitet
      If($Zeile -match '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') {
        
        # Leere Hashtable erstellen um die einzelnen Werte abzulegen
        $Result = @{}
    
        # Gefundene IPv4 Adresse aus der automatischen Variable $Matches auslesen
        # und als Name = Wert paar in an die Hashtable anfügen
        $Result.IPAddresse = $Matches[0]
    
        # Iv4 Adresse von der Zeile entfernen um leichter weiterarbeiten zu können
        # und Leerzeichen an den Enden entfernen
        $Zeile = $Zeile.Replace($Matches[0],'').Trim()
    
        # Zeile wird an den Leerzeichen aufgetrennt (ein Array wird erzeugt)
        $ZeilenArray = $Zeile -Split '\s+'
    
        # Standort befindet sich am Index 0  im Zeilen Array
        # und als Name = Wert paar in an die Hashtable anfügen
        $Result.Standort = $ZeilenArray[0]
        # Raum befindet sich am Index 1  im Zeilen Array
        # und als Name = Wert paar in an die Hashtable anfügen
        $Result.Raum = $ZeilenArray[1]
        # Da der Treshold ein Leerzeichen enthält, befindet sich am Index 2 im Zeilen Array
        # und als Name = Wert paar in an die Hashtable anfügen
        $Result.Treshold = $ZeilenArray[2]
            # Der Kontakt hat den Index 3 im Zeilen Array
        # und als Name = Wert paar in an die Hashtable anfügen
        $Result.Kontakt = $ZeilenArray[3]
    
        # POWERSHELL VERARBEITET OBJEKTE!!!!!!!!!!
        # Deshalb sollte man aus seinen Daten immer Objekte erzeugen
        # eine Hashtable ist einem Objekt SEHR, SEHR ähnlich
        # wir erzeugen aus der Hashtable ein Objekt
        # das erzeugte Objekt wird wieder in die Pipeline ausgegeben
        New-Object -TypeName PSObject -Property $Result
      }
    }


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Freitag, 27. März 2015 12:08

Alle Antworten


  • Die Treshold-Werte befinden sich in einer Textdatei mit anderen zusätzlichen Infos (ganz einfach dargestellt), sodass auch andere diese Werte noch für Ihre Niederlassungen festlegen können.

    Nun versuche ich über Powershell lediglich die Treshold-Werte einzulesen, damit ich damit Arbeiten kann.

    Um Dir Helfen zu können, müssen wir wissen, wie deine Textdatei aussieht. Erst dann können wir dir sagen, wie du die Daten aus der Textdatei herausfischen oder filtern kannst.

    Am besten ist es natürlich wenn die Textdatei ein gut strukturierter Text ist, wie es z.B. CSV oder XML ist.

    Um Unstrukturierte Textdateien mit der PowerShell einzulesen nimmt man das Cmdlet Get-Content.
    Um CSV einzulesen das Cmdlet Import-CSV. Bei XML geht man anders vor.


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Freitag, 27. März 2015 06:35
  • Die Textdatei wollte ich als Screenshot anfügen, leider durfte ich das noch nicht, da ich mein Konto grade erst erstellt worden ist.

    Ich hänge es mal so an.

    Genauso steht es in der Textdatei.(Kann sie leider immer noch nicht anhängen)
    Ist eine 1 zu 1 Kopie (Habs jetzt mit der "Codeblock" - Funktion hier reingestellt)

    IP-Addresse	Standort	Raum	Treshold	Kontakt
    
    192.168.101.10	Hannover 	2.20	|20|30|40|	ABC@XXXX.com
    192.168.101.11	Hamburg		2.22	|25|35|45|	DEF@XXXX.com
    192.168.101.12	Berlin		1.11	|30|40|50|	GHI@XXXX.com

    Einlesen an sich via get-content ist ja kein Problem.

    Nur würde ich das gerne für jeden Treshold wert über "foreach" tun :/

    Danke für die Hilfe

    Gruß

    Klotschek




    • Bearbeitet Klotschek Freitag, 27. März 2015 08:29
    Freitag, 27. März 2015 08:26
  • Hallo Klotschek!

    Ich kann da leider kein ordentlich strukturierter Text erkennen, man könnte das als CSV verarbeiten wenn das ternnzeichen der einzelnen Spalten immer gleich ist und nicht im Text einer Spalte vorkommt.

    Deshalb machen wir das mit dem so genannten Text-Parsing und wir schreiben den Code so, damit er den Text parst.
    Ein Parser wird dazu verwendet, einen Text in eine neue Struktur zu übersetzen oder Daten aus dem Text zu extrahieren. Der Programmierer von dem Parser versucht in dem Text die Struktur zu erkennen und diese Struktur in einen Code umzusetzen. Das Ergebnis sollte bei der PowerShell immer ein Objekt sein das die Daten in Name = Wert paaren enthält.

    Parsen von unstrukturiertem Text ist leider oft sehr fehleranfällig und sollte die letzte aller Optionen sein.

    Get-Content liest eine Textdatei Zeile für Zeile ein und gibt die Zeile dann in die Pipeline. Nun kann man für jede Zeile (for each) einen Code ausführen lassen.

    Text kann man in PowerShell mit Hilfe der .NET Methoden von der Klasse System.String verarbeiten oder mit “Regulären Ausdrücken” oder Englisch: Regular Expression.
    Weil der Name “Regular Expressions” etwas unhandlich ist, werden diese Kurz auch “RegEx” genannt.

    # Aus jeder Zeile von der Datei wird ein echtes Objekt extrahiert
    Get-Content "C:\Pfad\zur\Datei.txt" | ForEach-Object {
      # Das Aktuelle Objekt (die Zeile), das in der Pipeline ist ist in der Automatischen Variable $_ 
        
      # Variable in andere Variable übertragen und Leerzeichen an den Enden entfernen
      $Zeile = ($_).Trim()
    
      # IPv4 Adresse mit Regex aus der Zeile holen
      # Wenn die Zeile mit einer IPv4 beginnt wird sie verarbeitet
      If($Zeile -match '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') {
        
        # Leere Hashtable erstellen um die einzelnen Werte abzulegen
        $Result = @{}
    
        # Gefundene IPv4 Adresse aus der automatischen Variable $Matches auslesen
        # und als Name = Wert paar in an die Hashtable anfügen
        $Result.IPAddresse = $Matches[0]
    
        # Iv4 Adresse von der Zeile entfernen um leichter weiterarbeiten zu können
        # und Leerzeichen an den Enden entfernen
        $Zeile = $Zeile.Replace($Matches[0],'').Trim()
    
        # Zeile wird an den Leerzeichen aufgetrennt (ein Array wird erzeugt)
        $ZeilenArray = $Zeile -Split '\s+'
    
        # Standort befindet sich am Index 0  im Zeilen Array
        # und als Name = Wert paar in an die Hashtable anfügen
        $Result.Standort = $ZeilenArray[0]
        # Raum befindet sich am Index 1  im Zeilen Array
        # und als Name = Wert paar in an die Hashtable anfügen
        $Result.Raum = $ZeilenArray[1]
        # Da der Treshold ein Leerzeichen enthält, befindet sich am Index 2 im Zeilen Array
        # und als Name = Wert paar in an die Hashtable anfügen
        $Result.Treshold = $ZeilenArray[2]
            # Der Kontakt hat den Index 3 im Zeilen Array
        # und als Name = Wert paar in an die Hashtable anfügen
        $Result.Kontakt = $ZeilenArray[3]
    
        # POWERSHELL VERARBEITET OBJEKTE!!!!!!!!!!
        # Deshalb sollte man aus seinen Daten immer Objekte erzeugen
        # eine Hashtable ist einem Objekt SEHR, SEHR ähnlich
        # wir erzeugen aus der Hashtable ein Objekt
        # das erzeugte Objekt wird wieder in die Pipeline ausgegeben
        New-Object -TypeName PSObject -Property $Result
      }
    }


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Freitag, 27. März 2015 12:08
  • Brauchst du hier noch Hilfe? Wenn nicht markiere bitte Peters Antwort als "Antwort".

    Grüße, Denniver


    Blog: http://bytecookie.wordpress.com

    Kostenloser Powershell Snippet Manager v3: Link
    (Schneller, besser + einfacher scripten.)

    Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
    Warum das Ganze? Hier gibts die Antwort.

    Donnerstag, 2. April 2015 11:45
    Moderator