BNils 10 Geschrieben 12. Januar 2010 Melden Teilen Geschrieben 12. Januar 2010 Hallo, ein schönes Forum habt ihr hier :) Ich habe ein Problem und zwar möchte ich aus einer textdatei (endung .log) nur die letzte Zeile auslesen und in dieser Zeile nach einem Wort suchen (z.B. quit). Wie kann ich das anstellen? Gruß Nils Zitieren Link zu diesem Kommentar
NilsK 2.934 Geschrieben 12. Januar 2010 Melden Teilen Geschrieben 12. Januar 2010 Moin, etwas mehr Informationen benötigen wir schon: Was ist das Ziel des Ganzen? Von welcher Scripting-Sprache/-Umgebung reden wir? Geht es um eine neue Lösung oder willst du etwas Bestehendes erweitern? Geht es um eine einmalige oder eine wiederhiolte Aufgabe? Welchen Umfang hat die Logdatei? usw. usf. Gruß, Nils Zitieren Link zu diesem Kommentar
BNils 10 Geschrieben 12. Januar 2010 Autor Melden Teilen Geschrieben 12. Januar 2010 Okay, das habe ich vergessen :) Also es geht um die Windows PowerShell. Die Log file kann mehr als 80.000 Zeilen haben, je nach dem wann der Fehler auftritt. Im Moment Prüfe ich immer ob der Service Status auf Running steht und wenn nicht starte ich ihn. Manchmal passiert es aber, das der Service auf Running steht, aber durch ein Fehler der Service nicht mehr richtig arbeitet, in dem Fall taucht in einer Zeile ein quit auf. Danach passiert dann ncihts mehr in der log. Und in dem Fall möchte ich den service halt neustarten. Gruß Nils EDIT: Das einzige was mir so einviel, war mit folgendem Code die Zeilen zu zählen... aber das dauert eigentlich etwas zu lange... desshalb habe ich den ansatz nicht weiter verfolgt. function getZeile ($zeile) { $datei = Get-content "C:\Program Files\Service1\service.log" $a = 0 $datei | Foreach-Object { $a++} return $a } Zitieren Link zu diesem Kommentar
BNils 10 Geschrieben 13. Januar 2010 Autor Melden Teilen Geschrieben 13. Januar 2010 kann mir keiner helfen? Gruß Nils Zitieren Link zu diesem Kommentar
phoenixcp 10 Geschrieben 13. Januar 2010 Melden Teilen Geschrieben 13. Januar 2010 Lass den Leuten mal ein wenig Zeit. Drängeln hat noch keinem geholfen und man macht sich auch nicht unbedingt beliebt damit. ;) Zitieren Link zu diesem Kommentar
NilsK 2.934 Geschrieben 13. Januar 2010 Melden Teilen Geschrieben 13. Januar 2010 Moin, ich habe keine vollständige Lösung, nur den Tipp es mal mit dem Log Parser zu versuchen. Der kann einige Dinge sehr effizient. Kostenloser Download bei Microsoft. Gruß, Nils Zitieren Link zu diesem Kommentar
BNils 10 Geschrieben 13. Januar 2010 Autor Melden Teilen Geschrieben 13. Januar 2010 (bearbeitet) Schade, aber vielleicht ja jemand anders... Den LogParser schaue ich mir mal an Danke EDIT: Habe die Lösung gefunden, um nur die letzte Zeile auszulesen (überspringt leere Zeilen): Get-Content c:\scripts\test.log | Select-Object -last 1 bearbeitet 13. Januar 2010 von BNils Zitieren Link zu diesem Kommentar
Dukel 454 Geschrieben 13. Januar 2010 Melden Teilen Geschrieben 13. Januar 2010 if ((Get-Content file.log | Select-Object -Last 1) -match "quit"){ #Your Code here } Oder ... (get-Content file.log)[(get-Content file.log).count-1] ... Zitieren Link zu diesem Kommentar
Dukel 454 Geschrieben 13. Januar 2010 Melden Teilen Geschrieben 13. Januar 2010 Off-Topic: [...]EDIT: Das einzige was mir so einviel, war mit folgendem Code die Zeilen zu zählen... aber das dauert eigentlich etwas zu lange... desshalb habe ich den ansatz nicht weiter verfolgt.function getZeile ($zeile) { $datei = Get-content "C:\Program Files\Service1\service.log" $a = 0 $datei | Foreach-Object { $a++} return $a } Zur Info:Das Zeilen zählen geht schneller: function getZeile(){ return (Get-content "C:\Program Files\Service1\service.log").count-1 } Zitieren Link zu diesem Kommentar
BNils 10 Geschrieben 13. Januar 2010 Autor Melden Teilen Geschrieben 13. Januar 2010 (bearbeitet) if ((Get-Content file.log | Select-Object -Last 1) -match "quit"){ #Your Code here } Das ist super, dann habe ich eine Pipe weniger :) Danke @Dukel EDIT: Kann es sein, das er mit -last trotzdem vorne anfängt und jede Zeile durchläft bis er bei der letzten ist? Kann man das anders machen, weil es dauert bei meiner log (80.000 Zeilen) lange bis er bei der letzten Zeile ist! bearbeitet 13. Januar 2010 von BNils Zitieren Link zu diesem Kommentar
P.Foeckeler 11 Geschrieben 16. Januar 2010 Melden Teilen Geschrieben 16. Januar 2010 Hallo Nils, mit Get-Content wird leider ebenfalls die gesamte Datei ausgelesen, deswegen dauert es so lange (Get-Content bringt immerhin als Ausgabe ein Array mit allen Zeilen der Datei....). Du mußt das schon direkt mit einem .NET FileStream oder was ähnlichem anpacken. Da kannst Du den Lese-Zeiger direkt aufs Ende setzen und gehst dann zurück, bis du zum erstem Ml auf Character 10 (Line Feed) triffst, das wäre dann der letzte Zeilenumbruch, von da ab liest Du dann die Zeile. So wird von der Datei wirklich nur die letzte Zeile gelesen. Allerdings ist der Powershell-Code sehr häßlich, weil wie gesagt ein .NET-Objekt benutzt werden muß. Hier ein möglicher Code-Entwurf (es gibt wahrscheinlich noch Probleme, wenn die Datei von einem anderen Programm gerade exklusiv geöffnet ist...): $path = "C:\test.txt" $reader = New-Object System.IO.StreamReader($path, $true) [long]$pos = $reader.BaseStream.Length - 1 while($pos -gt 0) { $reader.BaseStream.Position = $pos if ($reader.BaseStream.ReadByte() -eq 10) {break} $pos-- } $line = $reader.ReadLine() $reader.Close() $line Das gibt die letzte Zeile aus. Auch wenn diese eine Leerzeile ist. Um die letzte nicht-leere Zeile zu bekommen, müßte man ein bisschen was ändern... Gruß, Philipp Zitieren Link zu diesem Kommentar
BNils 10 Geschrieben 3. Februar 2010 Autor Melden Teilen Geschrieben 3. Februar 2010 Hier ein möglicher Code-Entwurf (es gibt wahrscheinlich noch Probleme, wenn die Datei von einem anderen Programm gerade exklusiv geöffnet ist...) Genau das ist nun das Problem :( Aber vielen dank, für die Idee! Gruß Nils Zitieren Link zu diesem Kommentar
P.Foeckeler 11 Geschrieben 3. Februar 2010 Melden Teilen Geschrieben 3. Februar 2010 OK, für einen kompletten Parallel-Zugriff mußt du erst einen System.IO.FileStream öffnen, da kann man entsprechende FileMode/FileAccess Parameter übergeben, den Streamreader erzeugst Du dann auf der Basis vom Filestream.....es müßte ungefähr so gehen: $path = "C:\test.txt" $open = [system.IO.FileMode]::Open $read = [system.IO.FileAccess]::Read $share = [system.IO.FileShare]::Read $stream = New-Object System.IO.FileStream(($path, $open, $read, $share) $reader = New-Object System.IO.StreamReader($path, $true) ...der Rest dann wie gehabt. :cool: Gruß, Philipp Zitieren Link zu diesem Kommentar
BNils 10 Geschrieben 4. Februar 2010 Autor Melden Teilen Geschrieben 4. Februar 2010 (bearbeitet) Das funktioniert nicht, er sagt immer noch das der Prozess von einem anderen Programm geöffnet ist... Hast du noch eine idee :) Gruß Nils EDIT: Ich habe das ganze nun mi tail.exe aus dem Windows Resource Kit gelöst... das funktioniert super :) Trotzdem danke bearbeitet 4. Februar 2010 von BNils Zitieren Link zu diesem Kommentar
blub 115 Geschrieben 10. Februar 2010 Melden Teilen Geschrieben 10. Februar 2010 ich habe mir eine LogDatei mit 140.000 Zeilen erstellt (3-mal das Windowsupdatelog in eine Textdatei kopiert) mit diesem Code bekomme ich auf einem virtuellen Win7-Rechner die letzte Zeile in weniger als 5 Sekunden zurück $inhalt=get-content c:\temp\windowsupdate.log $letzteZeile=$($inhalt.length) $inhalt[$letzteZeile-1] Welche Zeit strebst du denn an? cu blub Zitieren Link zu diesem Kommentar
Empfohlene Beiträge
Schreibe einen Kommentar
Du kannst jetzt antworten und Dich später registrieren. Falls Du bereits ein Mitglied bist, logge Dich jetzt ein.